Università Politecnica delle Marche
Facoltà di Ingegneria
Corso di Laurea Specialistica in Ingegneria Informatica
Dipartimento di Ingegneria dell'Informazione
CONTINUOUS INTEGRATION
IN UNA WEB AGENCY
Laureando:
Giorgio Mandolini
Relatrice:
Prof.ssa Claudia Diamantini
Anno Accademico 2010/2011
L’entusiasmo è quando le gambe iniziano il primo passo
ed il cuore è già a destinazione
Indice
Indice
1 – Introduzione............................................................................................................... 1
1.1 Obiettivi...................................................................................................................1
1.2 Trattazione degli argomenti ....................................................................................2
2 – La Continuous Integration....................................................................................... 3
2.1 – Definizione ed obiettivi........................................................................................3
2.2 – Ciclo di vita del software..................................................................................... 5
2.2.1 – Modello di sviluppo Waterfall...................................................................... 5
2.2.2 – Modello di sviluppo Iterativo....................................................................... 7
2.2.3 - Continuous Integration e modello di sviluppo iterativo................................7
2.3 – Panoramica di un ambiente di Continuous Integration...................................... 10
2.4 – Best practices della Continuous Integration.......................................................12
i
Indice
2.4.1 – Utilizzo di un sistema di controllo versione............................................... 12
2.4.2 – Centralizzare tutto il necessario................................................................. 13
2.4.3 – Automatizzare le build................................................................................14
2.4.4 – Build testate automaticamente....................................................................16
2.4.5 – Commit frequenti........................................................................................17
2.4.6 - Eseguire delle build private nelle workstation locali.................................. 18
2.4.7 – Non inviare codice diffettoso..................................................................... 20
2.4.8 – Eseguire una build ad ogni cambiamento.................................................. 20
2.5.9 – Non scaricare codice difettoso....................................................................21
2.4.10 – Riparare immediatamente le build difettose............................................. 21
2.5.11 – Trattare il database come il codice sorgente............................................ 22
2.6.12 – Garantire un feedback rapido ed efficiente...............................................24
2.5 – Vantaggi offerti ................................................................................................. 26
2.5.1 – Rilasciabilità del software.......................................................................... 26
2.5.2 – Rivelazione degli errori.............................................................................. 27
2.5.3 – Visibilità di progetto ed aumento della comunicazione............................. 28
2.5.4 – Qualità del codice.......................................................................................28
3 – Applicazione della metodologia: analisi iniziale................................................... 30
3.1 – Analisi della situazione iniziale......................................................................... 30
3.1.1 – Prima dell'introduzione del sistema di controllo versione...........................31
3.1.2 – Dopo l'introduzione del sistema di controllo versione................................32
ii
Indice
3.2 – Analisi delle mancanze...................................................................................... 34
3.2.1 – Environment eterogenei..............................................................................34
3.2.2 – Mancanza di controllo sull'integrazione.....................................................37
3.2.3 – Mancanza di visibilità di progetto.............................................................. 37
3.2.4 – Nessuna integrazione del database.............................................................38
3.2.5 – Difficoltà di ingresso nel progetto..............................................................39
3.2.6 – Difficoltà nel rilascio di demo................................................................... 39
3.2.7 – Difficoltà di rilascio dell'applicazione....................................................... 39
4 – Progettazione del cambiamento..............................................................................41
4.1 – Scelta degli strumenti......................................................................................... 41
4.1.1 – Sistema di controllo versione...................................................................... 42
4.1.2 – Web Server e DBMS...................................................................................42
4.1.3 – Build scripting system................................................................................ 43
4.1.4 – Strumenti di testing.....................................................................................44
4.1.5 – Server di Continuous Integration................................................................46
4.2 – Standardizzazione delle workstation e dei progetti............................................ 46
4.2.2 – Standardizzazione della struttura cartelle...................................................47
4.2.2.1 – _data...................................................................................................47
4.2.2.2 – library.................................................................................................48
4.2.2.3 – _test.....................................................................................................48
4.2.2.4 – web.....................................................................................................48
iii
Indice
4.2.2.5 – _xhtml.................................................................................................49
4.2.2 – Comandi fondamentali.............................................................................. 49
4.2.3 – Standardizzazione del database.................................................................. 50
4.3 – Introduzione del build scripting system............................................................. 50
4.3.1 – Il target build...............................................................................................51
4.3.2 – Il target make-sql........................................................................................53
4.3 – Introduzione di uno script di installazione.........................................................54
4.5 – Introduzione dei test...........................................................................................55
4.6 – Installazione del server di Continuous Integration............................................ 58
4.7 – Training del personale........................................................................................59
4.7.1 – Lezioni frontali........................................................................................... 59
4.7.2 – Redazione di documenti operativi.............................................................. 60
4.7.3 – Post sul corporate blog............................................................................... 60
5 – Risultati ottenuti...................................................................................................... 61
5.1 Soluzione del problema degli environment eterogenei..........................................61
5.2 Soluzione del problema di integrazione del codice.............................................. 62
5.3 Soluzione del problema della visibilità di progetto...............................................63
5.4 Soluzione del problema di integrazione del DB................................................... 66
5.5 Soluzione del problema di ingresso al progetto.................................................... 67
5.6 Soluzione del problema delle demo...................................................................... 69
5.7 Futuri sviluppi: automatizzare il deploy............................................................... 69
iv
Indice
6 – Bibliografia...............................................................................................................71
6.1 – Letteratura.......................................................................................................... 71
6.2 – Risorse e strumenti.............................................................................................72
v
1 – Introduzione
1 – Introduzione
La seguente tesi si occupa di descrivere il lavoro svolto in una web agency 1, presso la
quale è stata presa in considerazione l'adozione della pratica della Continuous
Integration. Verranno trattate tutte le fasi che hanno contribuito alla realizzazione del
lavoro: da uno studio iniziale della metodologia da introdurre, all'applicazione dei
cambiamenti necessari al fine di una sua corretta implementazione.
1.1 Obiettivi
L'obiettivo principale del lavoro svolto è lo studio e l'implementazione di un sistema
informativo che organizzi l'azienda secondo le best practices della Continuous
Integration, al fine di migliorare il processo di sviluppo software. Verranno introdotti
1 e-xtrategy s.r.l. – http://www.e-xtrategy.net/
1
1 – Introduzione
strumenti come un sistema di controllo versione ed un server di Continuous Integration,
affiancati ad un insieme di regole da rispettare per ottenere il rispetto della pratica ed il
raggiungimento dei benefici offerti.
1.2 Trattazione degli argomenti
Nel capitolo 2 viene illustrata la Continuous Integration, definendo quali sono i suoi
obiettivi ed il problema dell'integrazione del software; viene fornita una panoramica
generale di un ambiente tipico di C.I., delle best practices che lo caratterizzano e dei
vantaggi promessi dall'utilizzo di questa metodologia.
Il capitolo 3 si occupa dell'analisi delle mancanze ed inefficienze riscontrate in azienda:
viene fornita una descrizione della metodologia di sviluppo utilizzata prima e dopo
l'introduzione del sistema di controllo versione, analizzando i problemi riscontrati dal
team di sviluppo in entrambi i casi.
Nel capitolo 4 verranno illustrati tutti i cambiamenti necessari al fine di introdurre la
Continuous Integration. In questa fase di progettazione saranno motivate le scelte
tecniche, secondo due criteri: l'ambito di sviluppo dell'azienda (web application) e
l'eventuale preesistenza di strumenti già adatti alla Continuous Integration.
Il capitolo 5 descrive i risultati ottenuti a seguito dei cambiamenti introdotti nel capitolo
4, focalizzando l'attenzione, punto per punto, sui problemi riscontrati nel capitolo 3. In
questa fase verranno espresse infine delle conclusioni sul lavoro svolto ed eventuali
sviluppi futuri.
2
2 – La Continuous Integration
2 – La Continuous Integration
In questo capitolo viene illustrata la Continuous Integration, definendo quali sono i suoi
obiettivi ed il problema dell'integrazione del software; viene fornita una panoramica
generale di un ambiente tipico di C.I., delle best practices che lo caratterizzano e dei
vantaggi promessi dall'utilizzo di questa metodologia.
2.1 – Definizione ed obiettivi
La Continuous Integration è una pratica emersa nella comunità Extreme Programming
(XP)2, ed i principali sostenitori, Martin Fowler3 e Kent Beck4, iniziarono a parlarne
intorno al 1999.
2 Extreme Programming – http://www.extremeprogramming.org/
3 Martin Fowler – http://martinfowler.com/
4 Kent Beck – http://www.threeriversinstitute.org/Kent Beck.htm
3
2 – La Continuous Integration
In accordo con la definizione5 data da Martin Fowler, si può definire la Continuous
Integration una pratica di sviluppo software dove i membri di un team integrano il
proprio lavoro frequentemente, da una a più volte al giorno. Ogni integrazione deve
essere verificata da una build automatizzata, che include dei test, per individuare errori
di integrazione il più presto possibile e permettere ad un team di sviluppare software
rapidamente.
Il problema dell'integrazione non è nuovo nel campo dello sviluppo ed è tanto più
complesso quanto più crescono le dimensioni del software e del team che ne è incaricato
allo sviluppo: al crescere della complessità, infatti, cresce anche la necessità di integrare
e di garantire il corretto funzionamento di tutti i componenti sviluppati dai diversi
membri del team.
L'obiettivo principale della Continuous Integration è appunto quello di semplificare
l'integrazione del software, facendola diventare parte integrante del processo di sviluppo
anziché relegarla ad una fase successiva.
5 Continuous Integration, Martin Fowler – http://martinfowler.com/articles/continuousIntegration.html
4
2 – La Continuous Integration
2.2 – Ciclo di vita del software
Possiamo mettere a confronto due modelli di processo di svulippo software ed
analizzare l'impatto della fase di test/integrazione su ciascuno di essi:
•
modello tradizionale Waterfall o “A cascata”
•
modello Incrementale/Iterativo
2.2.1 – Modello di sviluppo Waterfall
Figura 2.1 – Modello di sviluppo Waterfall: il processo scorre dal basso verso l'alto, come
una cascata.
Nel modello di sviluppo waterfall ogni fase produce un output che è l'input della fase
successiva.
5
2 – La Continuous Integration
L'intero software passa per ciascuna fase:
1. Requirements: viene effettuata la raccolta, l'analisi e la ristrutturazione
dei requisiti. Vengono definiti i requisiti non elicitati in fase di raccolta,
che può essere eseguita più volte, presso i vari stakeholders del sistema.
2. Design: viene progettato il software, in modo da rispettare i requisiti
definiti nello step precedente. In questa fase viene scelta l'architettura,
definite le interfacce delle classi e le relazioni tra di esse.
3. Implementation: il team procede con lo sviluppo vero e proprio del
software, traducendo in linee di codice quanto progettato in fase di
design.
4. Verification: tutti i componenti implementati vengono messi insieme ed
il software testato. E' qui che avviene l'integrazione.
5. Maintenance: il software è entrato in produzione, in questa fase si
procede al suo mantenimento, come eventuali bug fix o aggiornamenti.
6
2 – La Continuous Integration
2.2.2 – Modello di sviluppo Iterativo
Figura 2.2 – Modello di sviluppo Iterativo, il processo evolve all'interno di ciascuna
iterazione, a seguito della quale avviene un rilascio di software già funzionante.
Nel modello di sviluppo iterativo, si riconoscono fasi simili al modello waterfall, ma in
questo caso non si fa passare l'intero software per ogni fase, bensì una sola porzione alla
volta.
Anche in questo modello ogni fase produce un output che è l'input della fase successiva,
con la differenza che al termine di ciascuna iterazione il software sarà aumentato di
funzionalità. Ad ogni iterazione si ha una fase di rilascio (deploy) di software già
integrato e funzionante. Esclusa la prima iterazione, tutte le successive avranno come
input il software già presente ed un insieme di nuovi requisiti da implementare.
2.2.3 - Continuous Integration e modello di sviluppo iterativo
Sulla base delle caratteristiche dei modelli di sviluppo precedentemente illustrati, si può
7
2 – La Continuous Integration
affermare che la Continuous Integration ben si coniuga con
una metodologia
incrementale/iterativa. Su questo tipo di modelli di sviluppo infatti, l'integrazione del
software è un evento che avviene frequentemente a differenza del modello a cascata, in
cui viene fatta solamente al termine dell'implementazione, per poi essere testata nella
sua interezza in fase di collaudo e verifica.
Il vantaggio di un modello iterativo sta quindi nel costo di gestione dei bug, sia di
sviluppo che di integrazione. E' riconosciuto infatti che tale costo è tanto più elevato
quanto più tardi viene scoperto.
La Continuous Integration ha inoltre come ulteriore scopo quello di individuare
eventuali errori ancora prima: questo significa che per rilevare malfunzionamenti non è
necessario attendere il termine dell'iterazione o dell'intero processo di sviluppo.
Di seguito due grafici qualitativi, per il costo di risoluzione di un bug:
Figura 2.3 – Andamento del costo di un bug in funzione del momento di rivelazione, per il
modello di sviluppo Waterfall.
8
2 – La Continuous Integration
Figura 2.4 – Andamento del costo di un bug in funzione del momento di rivelazione, per il
modello di sviluppo Iterativo.
Com'è possibile notare, nel caso di un approccio iterativo le tre macro fasi “Requisiti”,
“Sviluppo” e “Test” vengono ripetute ad ogni iterazione, portando ai seguenti vantaggi:
•
Requisiti aggiornati ad ogni iterazione: il cliente può decidere di
cambiare requisiti in corso d'opera, senza l'implicazione una completa
riscrittura del software.
•
Sviluppo incrementale: il software viene scritto sulla base dei requisiti
dell'iterazione corrente, che sono quindi temporalmente vicini ed a
priorità più alta. Il rischio di scrivere componenti inutilizzati o sovraingegnerizzati è relegato alla singola iterazione e non a tutto lo sviluppo.
•
Test frequenti: ciascuna nuova funzionalità aggiunta viene testata al
momento della sua introduzione, rispettando quindi il criterio per cui un
bug è tanto meno costoso quanto prima viene scoperto.
9
2 – La Continuous Integration
2.3 – Panoramica di un ambiente di Continuous Integration
Gli attori fondamentali in un ambiente di Continuous Integration sono:
•
Lo sviluppatore.
•
Un sistema di controllo versione.
•
Un sistema di automazione delle build.
•
Un sistema di testing delle build.
•
Un server di Continuous Integration.
Figura 2.5 – Panoramica di un ambiente di Continuous Integration, con i principali attori
che contribuiscono al funzionamento del sistema.
10
2 – La Continuous Integration
Il funzionamento generale di un sistema di Continuous Integration è il seguente:
1. Lo sviluppatore esegue i cambiamenti necessari al codice:
implementa la feature richiesta, fino a che non la ritiene completata.
Insieme ad essa, scrive i test automatici che la riguardano.
2. Esegue una build privata sulla propria workstation: attraverso il
processo di build vengono eseguiti tutti i task necessari alla corretta
preparazione del software, prima del suo rilascio. In questa fase, oltre
alla compilazione, intervengono i test automatici.
3. Invio del codice al repository: una volta soddisfatti tutti i test, lo
sviluppatore invia i propri cambiamenti al sistema di controllo versione.
4. Build di integrazione: il Continuous Integration server periodicamente
reperisce l'ultima versione del software dal repository ed effettua una
nuova build automatica, comprensiva di test, che sarà il prodotto dei
cambiamenti inviati da tutti gli sviluppatori del team.
5. Feedback: se il processo di build da parte del Continuous Integration
server va a buon fine, erro genera un feedback positivo (es: tramite email o un monitor ben visibile dal team) ed il software è pronto al
rilascio. Viceversa il feedback sarà negativo e la soluzione del problema
individuato diventa prioritaria rispetto lo sviluppo di nuove funzionalità
11
2 – La Continuous Integration
2.4 – Best practices della Continuous Integration
Di seguito verranno illustrate le pratiche fondamentali per implementare correttamente
un sistema di Continuous Integration e come esse influenzano il processo di sviluppo. E'
importante sottolineare che la Continuous Integration è in primis una pratica e come tale
agisce radicalmente sul processo di sviluppo.
2.4.1 – Utilizzo di un sistema di controllo versione
L’utilizzo di un sistema di controllo versione è un requisito fondamentale per costruire
un ambiente di Continuous Integration. Lo scopo di questo strumento è la gestione dei
cambiamenti del codice sorgente e di tutto il necessario per la corretta compilazione del
software.
L'obiettivo principale è quello di avere un repository centralizzato, che permetta di
gestire e monitorare i cambiamenti che avvengono sulla base di codice. Non vi è
preferenza sulla scelta dello specifico strumento: l'unico requisito è quello di avere un
unico punto di accesso al codice, detto “mainline” o “trunk”, mentre le differenze che
intercorrono tra i vari sistemi di controllo versione non sono influenti.
Con questo strumento si introduce la possibilità di rollback dei cambiamenti: viene
tenuta traccia della storia di ciascun file, fornendo la possibilità di tornare indietro in
caso di necessità.
12
2 – La Continuous Integration
2.4.2 – Centralizzare tutto il necessario
La Continuous Integration impone che il software e tutto il necessario al suo
funzionamento, compresi framework, librerie, dipendenze esterne, test e build script, sia
messo sotto controllo versione all’interno del repository: esso dovrà fungere da “single
source point” del codice e l'applicazione dovrà essere in grado di funzionare solamente
con ciò che vi è contenuto, senza interventi esterni o aggiunte manuali.
Questo è necessario per garantire uniformità negli environment di sviluppo: le librerie
che i client degli sviluppatori usano per ciascun progetto provengono dal repository e
non da fonti esterne, permettendo di:
1. Risparmiare tempo in termini di ricerca ed installazione delle librerie e
delle dipendenze da parte dello sviluppatore.
2. Eliminare il rischio di installare versioni di librerie non aggiornate, mal
funzionanti o non compatibili.
Oltre a ciò, viene aumentata la velocità di ingresso al progetto da parte di eventuali
nuovi membri del team: una volta ottenuto l'accesso al repository, non devono essere
compiute ulteriori azioni esterne ad esso.
13
2 – La Continuous Integration
2.4.3 – Automatizzare le build
Il processo di build non include la sola compilazione del codice, ma anche
un
determinato numero di azioni, tra le quali il setup e popolazione del database con valori
noti (fixtures), che permettono al software di essere correttamente “costruito” e reso
funzionante.
E' necessario rendere questo insieme di passaggi automatico attraverso un singolo script
di build perché in questo modo:
1. Si limita l’intervento umano: la probabilità di errori ed omissioni viene
ridotta, in quanto lo sviluppatore utilizza un singolo comando.
2. Si migliora la riproducibilità: tutti gli sviluppatori eseguono gli stessi
passaggi in maniera identica, evitando il cosiddetto “but it works on my
machine”, dove il software risulta funzionante su alcuni ambienti e non
su altri.
14
2 – La Continuous Integration
Figura 2.1 – Tipici step di un generico script di build. Lo script stesso deve essere
considerato parte del software e come tale soggetto ad evoluzione.
15
2 – La Continuous Integration
2.4.4 – Build testate automaticamente
Una delle peculiarità della Continuous Integration è l'utilizzo di test automatici che
devono essere inoltre inglobati nei build script. A build completata lo sviluppatore
conoscerà il risultato del proprio lavoro e grazie all'esito dei test sarà in grado di averne
confidenza sulla bontà.
Non è contemplata la verifica ed il collaudo manuale dell'applicazione, esplorando di
volta in volta ciascuna delle funzionalità richieste, perché è necessario evitare
omissioni, soprattutto nel modello di sviluppo che si sta introducendo. La fase di test
viene infatti ripetuta ad ogni build, non è umanamente possibile testare il software
manualmente numerose volte al giorno, per ogni cambiamento introdotto.
Testare le applicazioni manualmente porta alla cattiva pratica di non verificare quelle
parti di codice per le quali si da per scontato il corretto funzionamento, in quanto si
assume che le modifiche introdotto non influenzino certi punti del software. Questo,
sebbene logico, è comunque non accettabile in un ambiente in cui la garanzia di rilevare
errori il prima possibile è considerata una priorità. I test automatici servono ad evitare
questa situazione: minori saranno le assunzioni e maggiori saranno le garanzie di un
software effettivamente funzionante.
I test automatici sono sempre ripetibili nella stessa identica maniera, in qualsiasi istante:
ad ogni build verificano tutte le funzionalità per cui sono stati scritti, più velocemente
ed in maniera più affidabile di un umano. Non è pensabile che una persona riesca ad
eseguire un gran numero di volte la stessa batteria di test senza introdurre di volta in
16
2 – La Continuous Integration
volta piccole differenze, perché, proprio per natura, è influenzabile da molteplici fattori
non deterministici come l'umore, la concentrazione e la stanchezza.
I test automatici sono invece deterministici e si fanno carico di un compito ripetitivo e
noioso, ma al tempo stesso critico.
2.4.5 – Commit frequenti
Uno dei principi fondamentali per ottenere vantaggi dalla Continuous Integration è
quello di integrare “poco, presto e spesso”.
Più si attende prima di inviare codice al repository, più il processo di integrazione
richiederà del tempo, per via della maggior quantità di dati da integrare, oltre al fatto
che gli altri membri del team, nel frattempo, non avranno tenuto conto degli ultimi
cambiamenti.
Si possono utilizzare le tecniche a seguito descritte per aumentare la frequenza di
commit al repository:
1. Eseguire piccoli cambiamenti: non cambiare più componenti software
insieme ma scegliere piccoli task per i quali scrivere dei test automatici
ed implementare il codice necessario al loro soddisfacimento. Una volta
eseguiti e passati tutti i test, inviare il codice al repository.
2. Suddividere il lavoro in task atomici: in altre parole, favorire la
17
2 – La Continuous Integration
scrittura di “unit of work” a bassa interdipendenza, quindi semplici da
integrare, con codice più snello e meno prono a complessità. In altri
termini rispettare il “KISS principle” (Keep
It Simple, Smart) [4],
secondo il quale la migliore soluzione ad un problema, a parità di
risultati, è quella a complessità minore.
La principale motivazione a supporto di questa regola risiede nella probabilità di
introduzione di un bug a seguito di una commit. Possiamo infatti affermare che la
probabilità di introduzione di un errore di integrazione è funzione crescente del numero
delle linee di codice che hanno influenzato la modifica.
Per cui:
P bug (N 1 )⩽P bug ( N 1) se N 1⩽ N 2 ,
con N 1 , N 2 numero di linee di codice affette dalla modifica.
Ne consegue che piccoli cambiamenti integrati frequentemente, rappresentano un
criterio di sviluppo più sostenibile, in cui si punta più al non introdurre bug, piuttosto
che correggerli in un secondo momento.
2.4.6 - Eseguire delle build private nelle workstation locali
Prima di iniziare con lo sviluppo di nuove funzionalità, ciascun membro è tenuto a
scaricare dal repository l’ultima versione del software. A questo punto potrà lavorare
18
2 – La Continuous Integration
nella propria workstation, effettuando i cambiamenti necessari al completamento del
proprio lavoro. Una volta terminato dovrà essere effettuata una build del software sulla
workstation ed osservarne i risultati.
Se tutto procede correttamente, prima di inviare le proprie modifiche al repository,
scaricherà di nuovo da questo gli eventuali cambiamenti effettuati nel frattempo dagli
altri sviluppatori e rilancerà la build, integrando di fatto il software.
Se tutto va a buon fine, è stato fatto un primo passo verso l’integrazione: i cambiamenti
sono stati integrati ed è possibile aggiornare la code-base eseguendo la commit verso il
repository.
Figura 2.2 – Step fondamentali eseguiti dallo sviluppatore per eseguire una build di
integrazione locale.
19
2 – La Continuous Integration
2.4.7 – Non inviare codice diffettoso
In caso di fallimento dei test durante la build privata, lo sviluppatore dovrà correggere i
malfunzionamenti e rieseguire la build fino alla completa risoluzione dei problemi
riscontrati. Non potrà, in nessun caso, inviare modifiche al repository se i test non
certificano che esso è correttamente funzionante.
Con questa regola si minimizza la probabilità di avere software non funzionante nel
repository: la copia malfunzionante resterà confinata nella macchina dello sviluppatore
che si occuperà di ripararla.
2.4.8 – Eseguire una build ad ogni cambiamento
Ogni volta che il repository viene aggiornato con nuovi cambiamenti, il codice necessita
di essere ritestato per avere la garanzia che non siano stati introdotti dei difetti.
Successivamente alle build private, quindi, si esegue la vera e propria build di
integrazione, su di una macchina dedicata che deve riprodurre il più fedelmente
possibile il vero ambiente di produzione. Al pari dei client degli sviluppatori, è
importante che questa macchina sia priva di dipendenze e librerie spurie che non
provengano direttamente dal repository: in questo modo si accerta che il lavoro dello
sviluppatore sia ancora riproducibile e non dipenda da una particolare configurazione a
livello locale. L’integration build può essere manuale o effettuata automaticamente
tramite un Continuous Integration server.
20
2 – La Continuous Integration
Sebbene l'utilizzo di un integration server non sia obbligatorio, è comunque
raccomandato usarne uno: esso infatti rileverà i cambiamenti sul repository ed eseguirà
le build automaticamente, fornendo inoltre una dashboard con report sui test, code
coverage, strumenti di analisi aggiuntivi ed eventuale documentazione auto-generata.
2.5.9 – Non scaricare codice difettoso
Nell'ipotesi in cui la build di integrazione fallisca, nonostante siano state correttamente
effettuate le build private, sorge il problema della “broken build”: è entrato un bug nella
code base e tutti i membri del team che andranno a scaricarlo otterrebbero del software
non funzionante.
Quando questo avviene la pratica impone di non scaricare affatto il codice difettoso e,
se possibile, continuare lo sviluppo tramite la propria copia locale, sebbene non
aggiornata, per poi integrarla in un secondo momento.
Piuttosto che sviluppare eventuali workaround per far funzionare il software difettoso
nella propria workstation è preferibile aiutare gli altri membri del team a far tornare la
build nel suo corretto stato di funzionamento.
2.4.10 – Riparare immediatamente le build difettose
E' compito dello sviluppatore che ha eseguito l'ultima commit risolvere il problema di
una build difettosa. E' importante che questo venga fatto immediatamente, perché è un
21
2 – La Continuous Integration
problema che coinvolge tutto il team, che a questo punto non può avere fiducia su
quanto contenuto nel repository. Nell'ipotesi in cui la build di integrazione fallisca,
infatti, deve essere considerata come prioritaria la soluzione dei problemi emersi
piuttosto che lo sviluppo di nuove funzionalità.
Come detto precedentemente, è vietato scaricare codice non funzionante: di fatto la
regola descritta in precedenza attiverebbe subito tutto il team alla soluzione del
problema, in quanto non potrebbe aggiornare il codice delle macchine locali per
continuarne lo sviluppo.
2.5.11 – Trattare il database come il codice sorgente
Il database dell'applicazione fa parte del software e come tale deve essere posto sotto
controllo di versione.
Figura 2.2 – La sequenza dell'integrazione automatica del db. Il build script si occupa di
far eseguire lo script di definizione al DBMS, per poi procedere con l'inserimento dei dati.
22
2 – La Continuous Integration
E' compito del build script gestire il DB: così facendo si può tener traccia anche dei
cambiamenti effettuati sulla struttura e sui dati nella stessa maniera con cui viene
effettuato con il codice sorgente. Per fare ciò è necessario gestire su file le procedure di
Data Definition Language (DDL) e Data Manipulation Language (DML) ed aggiungerle
al repository, che in questo modo continua ad essere l'unica fonte a cui attingere per lo
sviluppo del sofware.
Figura 2.3 – Esempio di integrazione del database, dove entrambi gli sviluppatori possono
eseguire modifiche ai dati ed allo schema.
23
2 – La Continuous Integration
2.6.12 – Garantire un feedback rapido ed efficiente
E' importante che il processo di build rapido: come regola empirica ci si impone un
limite di attesa massimo di 10 minuti per il risultato della build (regola del “10 minute
build”). Questo è necessario al fine di non indurre gli sviluppatori ad accumulare troppe
linee di codice prima di rieseguire la build, andando contro uno dei principi cardine
della Contiuous Integration. Per evitare questo anti pattern sono previste più soluzioni:
1. Eseguire delle staged-build: le build private vanno accompagnate
solamente da test unitari e le build di integrazione divise in due: test
unitari prima (per individuare subito i problemi più grossolani) per le
build lanciate ad ogni commit e test più approfonditi (unitari e funzionali,
analisi del codice, delle dipendenze, del code-style, ecc) per build
lanciate in un successivo momento, per esempio schedulate in notturna o
in seguito al successo delle precedenti build eseguite immediatamente
dopo la commit.
2. Aumentare le risorse hardware: garantire una sufficiente potenza di
calcolo, sia per le workstation sia per la macchina dedicata
all'integrazione finale del codice.
Avere una build veloce serve all'ottenimento di un feedback rapido che deve essere
coadiuvato da meccanismi che lo rendano facilmente individuabile e interpretabile,
24
2 – La Continuous Integration
alcune soluzioni proposte dalla pratica sono:
•
Un monitor sempre ben visibile al team, sul quale è possibile vedere
continuamente lo stato delle build dei vari progetti.
•
Meccanismi di allarme visivi e/o sonori per segnalare malfunzionamenti
(lampada verde/rossa, allarme sonoro).
•
Una combinazione dei precedenti.
A prescindere dal criterio di feedback scelto, è importante che esso sia incentrato sulle
informazioni utili ed essenziali, tutto il superfluo aumenta il rischio di far passare
inosservati messaggi realmente importanti.
A tal proposito è utile considerare i seguenti fattori, tra essi correlati:
•
L'informazione: ciò che il sistema deve comunicare.
•
Il destinatario: chi deve ricevere il messaggio. Gli sviluppatori sono
interessati allo stato di funzionamento della build, mentre un Project
Manager è più interessato ad un andamento globale del progetto (es:
metriche sulla qualità del software).
25
2 – La Continuous Integration
•
Il modo: il meccanismo di comunicazione scelto, come ad esempio una
barra verde/rossa per lo stato di una build o un grafico (anziché dei dati
in forma tabellare) per il suo andamento nel tempo.
•
I tempi: le informazioni sono deperibili nel tempo. E' fondamentale che
esse giungano a destinazione e vengano correttamente interpretate entro
un determinato tempo massimo, altrimenti diventano inutili.
2.5 – Vantaggi offerti
Di seguito verranno illustrati i principali vantaggi offerti dal rispetto delle best pratices
imposte dalla Continuous Integration.
2.5.1 – Rilasciabilità del software
Grazie ad un approccio incrementale, lo sviluppo non è più eseguito orizzontalmente. In
altre parole la progettazione del software non viene più fatta a livelli (es: gui, business
logic, database) che poi vengono integrati, ma diventa verticale sulla singola
funzionalità in fase di realizzazione.
Nel primo caso il software è rilasciabile solamente al termine dell'integrazione finale di
tutti i livelli, mentre nel secondo ogni funzionalità porta già con se la porzione dei livelli
interessati. Grazie alle integrazioni continue tra tutte le funzionalità, nel repository è
sempre presente una versione funzionante del software, anche se incompleto, mentre nel
26
2 – La Continuous Integration
caso precedente ciò non è possibile, in quanto un livello interamente sviluppato non ha
alcuna utilità se il livello da cui dipende non è stato ancora completato.
Intero software
GUI
Business Logic
Database
Figura 2.4 – Sviluppo non incrementale: il software viene sviluppato orizzontalmente,
mentre l'integrazione è verticale.
Funzionalità 1
Funzionalità 2
Funzionalità 3
Funzionalità n
GUI 1
GUI 2
GUI 3
GUI n
Business Logic 1 Business Logic 2 Business Logic 3
Database 1
Database 2
Database 3
Business Logic n
Database n
Figura 2.5 – Sviluppo incrementale: il software viene sviluppato verticalmente, mentre
l'integrazione è orizzontale.
2.5.2 – Rivelazione degli errori
Il rispetto della pratica delle build private e l'utilizzo dei test automatici fornisce un
sistema efficiente di prevenzione e rivelazione degli errori, che vengono individuati
velocemente anche grazie ad un feedback opportuno. L'eseguire una build ad ogni
cambiamento è un supporto alla rivelazione istantanea dei bug, che restano confinati a
porzioni di codice limitate e recenti. Grazie a ciò la risoluzione di eventuali problemi
viene semplificata.
27
2 – La Continuous Integration
2.5.3 – Visibilità di progetto ed aumento della comunicazione
L'utilizzo di un repository in cui centralizzare tutti gli elementi che compongono il
software, coadiuvato da un meccanismo di feedback opportuno aumenta la visibilità del
progetto da parte del team, che in questo modo è in grado di monitorarne costantemente
l'andamento. In questo modo si ha un aumento di comunicazione sia interna che verso
l'esterno: è possibile infatti tenere aggiornato il cliente sull'andamento generale del
progetto e studiare con esso eventuali misure correttive o cambi di direzione, già prima
della scadenza finale.
2.5.4 – Qualità del codice
L'utilizzo di un Continuous Integration server permette di eseguire automaticamente e
continuamente una serie di task ripetitivi e dispendiosi, come ad esempio:
•
L'analisi della complessità del codice
•
L'analisi dell'interdipendenza tra classi
•
Il rispetto del code style
•
L'analisi della duplicazione del codice
•
L'analisi della copertura dai test
28
2 – La Continuous Integration
Tutte queste operazioni tendono ad aumentare la qualità del prodotto, è infatti possibile
scegliere di far fallire una build qualora una o più di queste metriche scendano al di
sotto di una soglia prestabilita ed imporre quindi il rispetto degli standard prefissati.
29
3 – Applicazione della metodologia: analisi iniziale
3 – Applicazione della metodologia: analisi iniziale
Questo capitolo si occupa dell'analisi delle mancanze ed inefficienze riscontrate in
azienda: viene fornita una descrizione della metodologia di sviluppo utilizzata prima e
dopo l'introduzione del sistema di controllo versione, analizzando i problemi riscontrati
dal team di sviluppo in entrambi i casi.
3.1 – Analisi della situazione iniziale
Al momento dell'analisi, l'azienda era già in una situazione di transizione verso l'utilizzo
di un sistema di controllo versione, nello specifico SVN6, per la gestione del codice.
Lo strumento era già stato introdotto e correttamente configurato, ma non erano ancora
state introdotte le conoscenze e la corretta disciplina per un suo utilizzo efficiente.
6 Apache Subversion – http://subversion.apache.org/
30
3 – Applicazione della metodologia: analisi iniziale
3.1.1 – Prima dell'introduzione del sistema di controllo versione
Lo sviluppo delle applicazioni web veniva effettuato tramite un server centrale
contenente i sorgenti, il webserver ed il DBMS necessario alla loro esecuzione: le
macchine client degli sviluppatori interagivano direttamente con esso.
Gli sviluppatori, connessi ai sorgenti tramite mount point su rete locale effettuavano i
cambiamenti necessari al completamento del proprio lavoro.
L'approccio era quindi centralizzato, e prevedeva i seguenti step:
1. Accesso alle risorse del server di sviluppo tramite rete LAN,
2. modifica diretta dei file sorgente dell'applicazione in sviluppo,
3. accesso all'applicazione tramite browser web per la verifica dei risultati.
Figura 3.1 – Flusso di lavoro dell'azienda prima dell'introduzione del sistema di controllo
versione.
31
3 – Applicazione della metodologia: analisi iniziale
Con questo approccio l'azienda ha lamentato vari inconvenienti, tra i quali:
•
Mancanza di uno storico delle modifiche ai files e di chi le avesse
effettuate.
•
Impossibilità di poter effettuare dei rollback immediati, che non
passassero necessariamente per il sistema di backup del server.
•
Possibilità di collisione tra sviluppatori che potevano avere la necessità
di modificare lo stesso file contemporaneamente.
•
Blocco del lavoro dell'intero team di sviluppo qualora uno sviluppatore
provocasse il malfunzionamento dell'applicazione.
3.1.2 – Dopo l'introduzione del sistema di controllo versione
Per i motivi appena citati si è proceduto all'installazione di Subversion sul server di
sviluppo e gradualmente migrare tutti i lavori all'interno del nuovo repository.
Il processo di sviluppo è quindi passato da centralizzato a distribuito: ogni client si
connette al repository contenente i sorgenti, li scarica in locale e lavora con essi, per poi
rimandarli al server una volta terminate le modifiche.
La modalità appena introdotta è sensibilmente differente da quella vista in precedenza:
ciascun client ora dovrà essere dotato di un proprio webserver per eseguire le
applicazioni e di un proprio DBMS qualora queste ne richiedano uno.
32
3 – Applicazione della metodologia: analisi iniziale
Figura 3.2 – Flusso di lavoro dopo l'introduzione del sistema di controllo versione.
Il nuovo processo di sviluppo è caratterizzato quindi dai seguenti step:
1. Installazione del progetto sulla workstation:
1. Modifica manuale del file degli host locale per navigare
l'applicazione web.
2. Creazione di un database dedicato all'applicazione.
2. Sviluppo del progetto:
1. Checkout del codice, dal repository verso la macchina client.
2. Sincronizzazione manuale del database, tramite l'importazione di
33
3 – Applicazione della metodologia: analisi iniziale
file SQL provenienti dalla versione “legacy” dell'applicazione o
salvati nel repository.
3. Modifica dei sorgenti in locale.
4. Accesso all'istanza locale dell'applicazione tramite browser web
per la verifica dei risultati.
5. Invio dei nuovi sorgenti al repository.
3.2 – Analisi delle mancanze
L'introduzione di SVN nel processo di sviluppo dell'azienda ha incontrato inizialmente
una certa inerzia a causa della prospettiva di sviluppo letteralmente invertita.
L'abitudine degli sviluppatori di lavorare direttamente con l'applicazione nel server di
sviluppo si è scontrata con l'avere tante copie locali per ciascuna workstation. Di
seguito, saranno descritti i probleami individuati.
3.2.1 – Environment eterogenei
Ogni client presenta delle differenze, più o meno marcate, a seconda delle preferenze
dello sviluppatore che ne fa uso o della configurazione hardware/software.
Tali differenze sono risultate essere:
•
il sistema operativo utilizzato (Linux / Mac OS)
•
la configurazione del webserver (es: i path fisici dove viene salvata
34
3 – Applicazione della metodologia: analisi iniziale
l'applicazione).
•
la configurazione del DBMS (es: eterogeneità delle credenziali di
accesso al database utilizzato da una determinata applicazione).
•
Le librerie esterne ed i framework necessari al funzionamento del
progetto che possono presentare discrepanze sul numero di versione o
risiedere in path differenti.
Di conseguenza quando l'applicazione viene scaricata sulla macchina locale potrebbe
non funzionare correttamente e necessitare di una riconfigurazione.
Dato per assunto che tutte le applicazioni siano ben scritte e quindi parametrizzabili
tramite un singolo file di configurazione (es: config.xml) resta comunque il problema
di dover gestire collisioni di configurazione che sono tante quante sono i client di
sviluppo, più la configurazione finale per l'ambiente di produzione, dove la release
dovrà lavorare per il cliente.
Lo scenario è quindi il seguente:
1. Lo sviluppatore scarica l'applicazione
2. Effettua la riconfigurazione
3. Lavora sull'applicazione
4. Invia le modifiche al repository
35
3 – Applicazione della metodologia: analisi iniziale
Tale modalità evidenzia subito un'inefficienza: si nota infatti che ad ogni commit sul
repository la configurazione viene di volta in volta sovrascritta, ed a causa di ciò si va
incontro a due problemi:
1. La necessità di riconfigurare l'applicazione ad ogni aggiornamento
ricevuto dal repository.
2. Nel repository non è mai presente una versione dell'applicazione che sia
già rilasciabile e correttamente configurata per l'ambiente di produzione.
Il primo problema è una criticità che abbassa l'efficienza e la produttività del team: oltre
al tempo necessario all'effettiva riconfigurazione si introduce un fattore di rischio
dovuto alla possibilità di commettere errori durante questa fase. In altre parole si sta
sprecando tempo in un task che non porta alcun valore: la riconfigurazione non
aggiunge funzionalità all'applicativo, tantomeno ne migliora alcune preesistenti,
pertanto ha valore pari a zero.
Il secondo problema è un fattore di rischio che potrebbe portare a problemi in fase di
rilascio dell'applicazione, che porta con se altri due svantaggi:
1.
Non si ha la certezza che l'applicativo sia effettivamente funzionante
una volta rilasciato nell'ambiente di produzione.
36
3 – Applicazione della metodologia: analisi iniziale
2.
La pubblicazione di nuove features è ogni volta rallentata dal processo
manuale di configurazione.
3.2.2 – Mancanza di controllo sull'integrazione
Con la modalità centralizzata ciascuno sviluppatore era costretto a lavorare su porzioni
indipendenti dell'applicativo, in quanto non vi era nessun meccanismo di sviluppo
concorrente.
Con l'introduzione di Subversion questo limite è stato rimosso: grazie al controllo di
versione è infatti possibile poter effettuare cambiamenti concorrenti anche sulle stesse
aree di codice e poter gestire le collisioni tramite i meccanismi di risoluzione offerti
dallo strumento.
Resta però il problema dell'integrazione, cioè garantire che la risoluzione dei conflitti
sia effettivamente corretta e non causi malfunzionamenti.
3.2.3 – Mancanza di visibilità di progetto
Diretta conseguenza del problema visto precedentemente è la mancanza di visibilità sul
progetto: il fatto che il software funzioni sulla workstation locale dello sviluppatore non
garantisce il corretto funzionamento della build presente nel repository.
Qualora due o più sviluppatori lavorino sulla stessa area di codice, al momento della
commit Subversion si occupa di segnalare l'avvenuta collisione e permetterne la
37
3 – Applicazione della metodologia: analisi iniziale
risoluzione del conflitto: sebbene questo sia un primo livello di protezione, non si ha
comunque la garanzia che l'integrazione sia avvenuta correttamente.
Ciascuno sviluppatore è infatti responsabile delle modifiche che introduce, ma senza un
meccanismo che permetta automaticamente di evidenziare effetti collaterali in altri punti
del codice si potrebbero introdurre inavvertitamente dei malfunzionamenti che in prima
analisi potrebbero non essere visibili.
3.2.4 – Nessuna integrazione del database
Con l'abbandono del server centrale si è passati da un un'unica istanza dell'applicazione
in sviluppo ad n istanze, una per ogni client coinvolto nel processo di sviluppo.
Replicare il codice in tutte le workstation locali non è visto come un particolare
problema, ma per quanto riguarda la gestione del database sono emerse alcune
problematiche:
•
Non esiste più un DBMS centralizzato, al quale tutti fanno riferimento
•
Non c'è un meccanismo di integrazione tra i cambiamenti ai dati e alla
struttura, effettuati nelle copie locali.
Tali problematiche, non emergevano invece con il vecchio approccio centralizzato: la
macchina di sviluppo era unica, come pure il DBMS e l'istanza dell'applicativo.
38
3 – Applicazione della metodologia: analisi iniziale
3.2.5 – Difficoltà di ingresso nel progetto
Una delle difficoltà avvertite dall'azienda è stata la difficoltà di ingresso nel progetto da
parte di nuovi membri del team.
E' necessario che tutto passi per un client locale, che deve essere configurato affinché
sia in grado di ospitare correttamente il progetto, anche per piccolissime modifiche.
Il tempo necessario al setup e bootstrap manuali dell'applicazione in locale, complice
anche l'eterogeneità degli environment precedentemente descritta, spesso supera il
tempo necessario all'implementazione delle modifiche richieste.
3.2.6 – Difficoltà nel rilascio di demo
Creare una demo del software significa consegnare al cliente una prima versione
funzionante di ciò che è attualmente in sviluppo dentro il repository. Questo processo è
risultato essere lento e macchinoso, in quanto eseguito manualmente.
Emerge quindi la necessità di automatizzare questa fase e studiare un meccanismo che
automaticamente si occupi di scaricare dal repository l'ultima versione del software e
pubblicarla in un server di demo.
3.2.7 – Difficoltà di rilascio dell'applicazione
Un problema simile a quello del rilascio di demo, ma molto più delicato e critico è
39
3 – Applicazione della metodologia: analisi iniziale
quello del rilascio ufficiale. La differenza sta nel fatto che in questo caso la destinazione
non è più il server di demo, in cui eventuali malfunzionamenti o imprecisioni possono
essere ancora tollerati, ma nel server ufficiale di produzione, dove l'applicazione entrerà
definitivamente in produzione per il cliente. Diventa quindi necessario l'utilizzo di
strumenti come FTP o SFTP per l'invio dei files e prestare la massima attenzione nel
non commettere errori in un ambiente in cui questi non sono assolutamente tollerabili.
In questa fase si sta consegnando il software al cliente, è quindi necessario ripulirlo di
tutti gli assets aggiuntivi come i files di gestione di Subversion e tutto ciò che non è
necessario: mantenere questi files potrebbe rappresentare una vulnerabilità del sistema,
oltre che uno spreco di spazio.
40
4 – Progettazione del cambiamento
4 – Progettazione del cambiamento
In questo capitolo verranno illustrati tutti i cambiamenti necessari al fine di introdurre la
Continuous Integration. In questa fase di progettazione saranno motivate le scelte
tecniche, secondo due criteri: l'ambito di sviluppo dell'azienda (web application) e
l'eventuale preesistenza di strumenti già adatti alla Continuous Integration.
4.1 – Scelta degli strumenti
La scelta è stata fatta preferendo tutti quegli strumenti inerenti alle tecnologie web,
reputati quindi più adatti per la tipologia di applicazioni sviluppate dall'azienda.
41
4 – Progettazione del cambiamento
4.1.1 – Sistema di controllo versione
E' stato scelto il sistema di controllo di versione Subversion 7 (o SVN) in quanto già
utilizzato dall'azienda presa in esame. Per quanto riguarda il server contenente il
repository non sono state effettuate modifiche, perché già correttamente configurato per
essere usufruito sia dalla rete locale interna che da remoto, tramite una connessione
sicura SSH.
Sono state dotate di un client SVN tutte le workstation che non ne erano munite, in
modo da renderlo disponibile per tutta l'azienda.
4.1.2 – Web Server e DBMS
L'azienda sviluppa principalmente applicazioni web in PHP, per le quali il tipico web
server è Apache8. Il DBMS scelto, sempre in relazione al tipo di software sviluppato, è
MySQL9.
La tipica installazione scelta è quindi di tipo LAMP (Linux, Apache, MySQL, PHP) per
i client di tipo Linux, oppure MAMP (Mac, Apache, MySQL, PHP) per i client basati su
sistema operativo Mac OS. Per entrambe è stato scelto il software Zend Server10.
Non sono state infine rilevate macchine dedicate allo sviluppo, dotate di sistema
operativo Windows.
7
8
9
10
Apache Subversion – http://subversion.apache.org/
Apache HTTP Server Project – http://httpd.apache.org/
Oracle MySQL – http://www.mysql.com/
Zend Server – http://www.zend.com/products/server/
42
4 – Progettazione del cambiamento
4.1.3 – Build scripting system
Come strumento per lo sviluppo ed esecuzione degli script di build è stato scelto
Phing11, in quanto specifico per il linguaggio PHP, con il quale è possibile scrivere
eventuali plugin o estensioni. Esso fa uso di un file di build (di tipo XML), attraverso il
quale è possibile definire una serie di attività (dette “target”) composte da operazioni
(detti “task”) da eseguire in automatico.
I task che si possono eseguire attraverso Phing coprono ampiamente le richieste della
Continuous Integration, infatti con essi si possono effettuare, tra le altre, le seguenti
operazioni:
•
operazioni su file system
•
operazioni su database
•
esecuzione di test automatici
•
operazioni FTP ed SFTP
•
interazione con la shell fornita dal sistema operativo
11 Phing – http://www.phing.info/
43
4 – Progettazione del cambiamento
4.1.4 – Strumenti di testing
Con i test unitari si verifica il funzionamento dell'applicazione ad un livello atomico: le
classi dell'applicazione vengono testate singolarmente e si testano uno a uno i metodi
che le compongono. Con i test funzionali si testa l'applicazione ad un livello più alto:
attraverso una procedura automatizzata si simula l'interazione uomo-macchina e si
verifica se i risultati ottenuti combaciano con quelli attesi.
Per lo sviluppo dei test automatici sono stati scelti i seguenti software:
1. PHPUnit12 per la scrittura di test unitari.
2. Selenium IDE e Selenium RC13 per i test funzionali.
La scelta di PHPUnit è motivata dal fatto che l'azienda sviluppa le proprie applicazioni
utilizzando il linguaggio PHP. PHPUnit fa inoltre parte della famiglia dei framework di
testing xUnit (disponibile per un elevato numero di linguaggi tra cui Java con JUnit e
.NET con NUnit) con la quale condivide la sintassi e la modalità di funzionamento.
12 PHPUnit – http://www.phpunit.de/
13 Selenium , Web Browser Automation – http://seleniumhq.org/
44
4 – Progettazione del cambiamento
Figura 4.1 – Screenshot del software Selenium IDE, con il quale effettuare la registrazione
delle sessioni di navigazione.
Selenium IDE e Selenium RC sono stati invece scelti in quanto le applicazioni
sviluppate dall'azienda sono nello specifico dei siti internet: Selenium IDE
consente di registrare delle sessioni di navigazione, mentre Selenium RC in
accoppiata a PHPUnit è in grado di rieseguirle senza intervento umano, lanciando
una istanza di browser reale.
45
4 – Progettazione del cambiamento
4.1.5 – Server di Continuous Integration
Durante la fase di analisi in azienda, è stato scelto Hudson 14 come server di Continuous
Integration, in quanto di agevole installazione e configurazione, ma soprattutto
integrabile con gli strumenti introdotti in precedenza.
Hudson offre infatti supporto a:
1. Numerosi sistemi di controllo di versione, tra cui SVN
2. Vari linguaggi di build scripting, tra cui phing
Supporta infine in maniera soddisfacente l'integrazione con i risultati forniti dai test
eseguiti con il framework PHPUnit, permettendo la visualizzazione nella dashboard sia
dei risultati che di ulteriori dettagli come la code coverage.
4.2 – Standardizzazione delle workstation e dei progetti
A seguito dell'installazione degli strumenti elencati precedentemente, tutte le
workstation sono state configurate in modo da avere a disposizione tutti i comandi
necessari ad eseguire il processo di build del software e tutte le operazioni ad esso
connesse che vanno automatizzate.
14 Hudson Continuous Integration – http://hudson-ci.org/
46
4 – Progettazione del cambiamento
Oltre alla standardizzazione degli environment delle worstation si è proceduto con la
definizione di una struttura comune a tutti i progetti.
4.2.2 – Standardizzazione della struttura cartelle
Per ciascun progetto è stata definita una struttura cartelle consistente, che va sempre
rispettata con rigore, in modo da permettere a ciascun membro del team di reperire il
necessario nel più breve tempo possibile e senza ambiguità.
Di seguito la struttura scelta, comprensiva dei files fondamentali:
.
├──
│
│
│
│
│
│
├──
├──
│
│
├──
│
├──
└──
_data
├── database.create.db.sql
├── database.dati.sql
├── database.struttura.sql
├── install.sh
├── LINUX_dominio.conf
└── MAC_httpd.conf
library
_tests
├── functional
└── unit
web
└── index.php
_xhtml
build.xml
Figura 4.2 – Struttura cartelle scelta, da rispettare per ciascun progetto presente nel
repository dell'azienda.
4.2.2.1 – _data
In questa cartella sono presenti tutti i dati necessari all'installazione del progetto e la
47
4 – Progettazione del cambiamento
popolazione dei dati a partire da valori noti.
Qui possiamo trovare i senguenti files:
•
database.create.db.sql
•
database.dati.sql
•
database.struttura.sql
•
install.sh
per la creazione del database.
contiene i dati iniziali del database, detti fixtures.
contiene la struttura del database.
è uno script bash, per l'installazione del progetto nella
worskation locale (modifica al file degli host del sistema operativo e
creazione di un virtual host).
•
LINUX_dominio.conf
•
MAC_httpd.conf
contiene il virtual host per i sistemi Linux.
contiene il virtual host per i sistemi Mac OS.
4.2.2.2 – library
E' la cartella dedicata alle librerie ed ai framework utilizzati nel progetto.
4.2.2.3 – _test
E' la cartella sulla quale vengono appoggiati tutti i files relativi ai test. E' ulteriormente
suddivisa in due sotto cartelle, unit e functional, contenente rispettivamente i test
unitari e funzionali.
4.2.2.4 – web
E' la cartella che viene puntata dai virtual host e sulla quale è presente il file index.php
48
4 – Progettazione del cambiamento
di ciascun progetto. Contiene la vera e propria web application, nello specifico tutti i
files che vanno resi accessibili all'esterno.
La suddivisione dei files all'interno di essa dipenderà dagli specifici progetti.
4.2.2.5 – _xhtml
E' utilizzata dagli sviluppatori per la creazione dei templates dinamici. Contiene la
versione statica della web application, ossia tutti i files HTML da utilizzare come
modello per lo sviluppo del frontend. Sono il risultato del lavoro del frontend developer,
che esegue il montaggio della grafica progettata dal designer.
4.2.2 – Comandi fondamentali
Di seguito un riassunto dei comandi messi a disposizione dopo l'aggiornamento di tutte
le workstation:
Comando
Descrizione
phing
Per eseguire la build del software
mysql
Per eseguire operazioni sul database
mysqldump
phpunit
Per eseguire il dump del database su file
Per eseguire i test automatici
Tabella 4.1 – Lista dei comandi messi a disposizione su ciascuna worsktation per
implementare la Continuous Integration.
In questo modo è stato possibile creare un unico script di build standardizzato per tutti
client e tutti i progetti, in modo da garantire una configurazione omogenea.
49
4 – Progettazione del cambiamento
4.2.3 – Standardizzazione del database
Per eliminare i problemi di eterogeneità è stata definita una convenzione sul nome del
database da utilizzare per ogni progetto e le credenziali di autenticazione (utente
MySQL) con il quale è possibile interagire con esso. In questo modo è stato garanto a
ciascuno sviluppatore di gestire il DBMS della propria workstation in autonomia,
mantenendo private le proprie credenziali di amministratore, in quanto sono quelle
relative al progetto ad essere condivise: l'applicazione, se non diversamente configurata,
fa riferimento sempre alle stesse credenziali di accesso al DB.
Sono state poi create le procedure SQL necessarie al setup e popolazione del database,
ed in seguito salvate nel repository, insieme a tutto il necessario per ottenere tramite un
singolo comando:
1. Un utente di progetto attivo e configurato, con le proprie credenziali ed i
permessi correttamente configurati per il proprio database.
2. Un database dal nome univoco per il singolo progetto, con la propria
struttura ed eventualmente popolato con ben determinati dati iniziali
(detti anche fixtures).
4.3 – Introduzione del build scripting system
E' stato creato un generico file build.xml ed implementati dei target comuni ad ogni
50
4 – Progettazione del cambiamento
progetto. Questo file viene di volta in volta personalizzato secondo le esigenze e posto
sotto controllo di versione insieme ad esso. In questo modo ciascuna applicazione ha il
proprio script di generazione della build che diventa parte integrante del software e
come tale potrà essere migliorato o ampliato di nuove funzionalità. Sono stati definiti
due target fondamentali per ciascun progetto: “build” e “make-sql”.
1.
<?xml version="1.0" encoding="UTF-8"?>
2.
<project name="e-xtrategy" basedir="." default="build">
3.
<property name="db.name" value="e-xtrategy" />
4.
<property name="db.user" value="root" />
5.
<property name="db.password" value="" />
6.
7.
8.
9.
<target name="build">
<!-- target definition -->
</target>
10.
11.
12.
13.
<target name="make-sql">
<!-- target definition -->
</target>
14.
15.
</project>
Listato 4.1 – Esempio di file build.xml, contenente i target fondamentali “build” e “makesql”.
4.3.1 – Il target build
Il target build si occupa dell'effettivo setup dell'applicazione automatizzando la gran
parte delle attività che altrimenti sarebbero state manuali e soggette ad errore.
51
4 – Progettazione del cambiamento
Tali attività, tipicamente, sono:
1. Cancellazione dei file temporanei ed eliminazione di residui di vecchie
build.
2. Impostazione dei permessi di lettura e scrittura nelle directory.
3. Setup del database e dell'utente di accesso tramite le procedure SQL viste
precedentemente.
4. Esecuzione di test automatici
1.
2.
<target name="build">
<if>
3.
<equals arg1="${db.password}" arg2=""/>
4.
<then>
<property name="pstring" value=""/>
5.
6.
</then>
7.
<else>
<property name="pstring" value="-p${db.password}"/>
8.
9.
</else>
10.
</if>
11.
<exec command="mysql -u${db.user} ${pstring} < _data/$
{db.name}.create.db.sql" checkreturn="true"/>
12.
<exec command="mysql -u${db.user} ${pstring} ${db.name} <
_data/${db.name}.struttura.sql"checkreturn="true"/>
13.
<exec command="mysql -u${db.user} ${pstring} ${db.name} <
_data/${db.name}.dati.sql"checkreturn="true"/>
14.
</target>
Listato 4.2 – Esempio di target “build” con cui viene creato e popolato il database,
partendo dai files sql presenti nel repository.
52
4 – Progettazione del cambiamento
4.3.2 – Il target make-sql
L'applicazione durante il suo funzionamento interagisce con il database inserendo,
modificando o cancellando dei record, oppure lo sviluppatore decide di effettuare dei
cambiamenti alla struttura di alcune tabelle o della struttura del database in generale.
Qualora lo sviluppatore intenda inviare la nuova versione del database al repository è
necessario innanzitutto che ne effettui il dump su file.
Questa fase è stata automatizzata creando il target make-sql: vengono effettuati il dump
della struttura e dei dati e salvati in due distinti files, che andranno a sostituire quelli
contenenti le procedure per la creazione e popolazione della vecchia versione del
database.
15.
16.
<target name="make-sql">
<if>
17.
<equals arg1="${db.password}" arg2=""/>
18.
<then>
<property name="pstring" value=""/>
19.
20.
</then>
21.
<else>
<property name="pstring" value="-p${db.password}"/>
22.
23.
</else>
24.
</if>
25.
<exec command="mysqldump -u${db.user} ${pstring} --skipcomments --no-create-info ${db.name} >_data/${db.name}.dati.tmp"
checkreturn="true"/>
26.
<exec command="mysqldump -u${db.user} ${pstring} --skipcomments --no-data ${db.name} >_data/${db.name}.struttura.tmp"
checkreturn="true" />
27.
<delete file="_data/${db.name}.dati.sql" />
28.
<delete file="_data/${db.name}.struttura.sql" />
29.
<move file="_data/${db.name}.dati.tmp" tofile="_data/$
53
4 – Progettazione del cambiamento
{db.name}.dati.sql" />
<move file="_data/${db.name}.struttura.tmp" tofile="_data/$
30.
{db.name}.struttura.sql" />
31.
</target>
Listato 4.3 – Esempio di target “make-sql” con cui struttura e dati del database vengono
fatti persistere su filesystem, prima dell'invio al repository.
Una volta effettuata la commit la nuova versione del DB sarà a questo punto presente
nel repository.
4.3 – Introduzione di uno script di installazione
Come illustrato in precedenza, per poter ottenere il funzionamento di ciascun website in
locale, sono necessarie alcune operazioni preliminari, che sono la modifica al file degli
host del sistema e la creazione di un virtual host per il webserver. Per facilitare
l'installazione di ciascun progetto nelle macchine locali è stato creato uno script bash.
1.
#!/bin/bash
2.
n=$(grep local.e-xtrategy.net /etc/hosts -c)
3.
if [ "$n" = 0 ]; then
echo 127.0.0.1 local.e-xtrategy.net >> /etc/hosts
4.
5.
fi
6.
cp LINUX_dominio.conf /etc/apache2/sites-available/www.extrategy.net.conf
7.
cd /etc/apache2/sites-available/
8.
a2ensite www.e-xtrategy.net.conf
9.
/etc/init.d/apache2 restart
Listato 4.4 – Esempio di file install.sh, per la modifica del file degli host e la creazione del
virtual host.
54
4 – Progettazione del cambiamento
4.5 – Introduzione dei test
Per testare l'applicazione nella build privata è stato creato il target “test” che si occupa
di lanciare PHPUnit configurato in modo da eseguire i test che sono stati scritti per
l'applicazione. I test automatici, come il file build.xml, vanno considerati parte del
software ed anch'essi posizionati all'interno del repository, nella cartella _test: in questo
modo una procedura di test scritta da uno sviluppatore va a beneficio di tutto il team che
può inoltre rivederla e migliorarla.
I test documentano le funzionalità del codice e ne verificano l'effettivo funzionamento:
se un requisito del software cambia, anche i test ad esso correlati verranno aggiornati.
1.
<?php
2.
require_once 'PHPUnit/Framework.php';
3.
require_once APPLICATION_PATH . '/models/User/CgaUser.php';
4.
require_once APPLICATION_PATH . '/models/User/CgaUsers.php';
5.
6.
class CgaUsersTest extends PHPUnit_Framework_TestCase {
7.
8.
/**
9.
* setup delle fixtures
10.
*/
11.
public function setUp() {
12.
$u1 = new CgaUser();
13.
$u1->anno_registrazione = 2009;
14.
15.
$u2 = new CgaUser();
16.
$u2->anno_registrazione = 2010;
17.
18.
$u3 = new CgaUser();
19.
$u3->anno_registrazione = 2008;
20.
21.
$this->_users = array($u1, $u2, $u3);
55
4 – Progettazione del cambiamento
$this->_cgaUsers = new CgaUsers($this->_users);
22.
23.
}
24.
25.
/**
26.
* testa il risultato dell'operazione su tutta la collection
27.
* l'operatore (mock)
28.
* che assegna sempre lo stato di confermato
29.
*/
30.
public function testAllSociOperation() {
31.
// Create a stub for the CgaUser class.
32.
$userMock = $this->getMock('CgaUser');
33.
// Configure the stub.
34.
$userMock->confirmed = true;
35.
36.
//Create a stub for the CgaUserChecker Operator class.
37.
$operator = $this>getMock('CgaUserChecker1', array('execute'));
38.
// Configure the stub.
39.
$operator->expects($this->any())
40.
->method('execute')
41.
->will($this->returnValue($userMock));
42.
43.
$this->_cgaUsers->operation(array($operator));
44.
foreach ($this->_cgaUsers as $user) {
45.
$this->assertTrue($user->confirmed);
46.
47.
}
}
48.
49.
/**
50.
* testa il risultato dell'operazione su tutta la collection
51.
* l'operatore (mock)
52.
* che assegna sempre lo stato di non confermato
53.
*/
54.
public function testNoSociOperation() {
55.
// Create a stub for the CgaUser class.
56.
$userMock = $this->getMock('CgaUser');
57.
// Configure the stub.
58.
$userMock->confirmed = false;
56
4 – Progettazione del cambiamento
59.
60.
//Create a stub for the CgaUserChecker Operator class.
61.
$operator = $this>getMock('CgaUserChecker1', array('execute'));
62.
// Configure the stub.
63.
$operator->expects($this->any())
64.
->method('execute')
65.
->will($this->returnValue($userMock));
66.
67.
$this->_cgaUsers->operation(array($operator));
68.
foreach ($this->_cgaUsers as $user) {
69.
$this->assertFalse($user->confirmed);
70.
71.
}
}
72.
73.
/**
74.
* testa il risultato di più operazioni sulla collection
75.
* il primo operatore assegna sempre lo stato di confermato
76.
* il secondo operatore assegna sempre l'anno 2010
77.
78.
*/
public function testMultipleOperations() {
79.
// Create a stub for the CgaUser class.
80.
$userMock = $this->getMock('CgaUser');
81.
// Configure the stub.
82.
$userMock->confirmed = true;
83.
84.
//Create a stub for the CgaUserChecker Operator class.
85.
$op1 = $this>getMock('CgaUserChecker1', array('execute'));
86.
// Configure the stub.
87.
$op1->expects($this->any())
88.
->method('execute')
89.
->will($this->returnValue($userMock));
90.
91.
$userMock2 = clone $userMock;
92.
$userMock2->anno_registrazione = 2010;
93.
94.
//Create a stub for the CgaUserChecker Operator class.
57
4 – Progettazione del cambiamento
95.
$op2 = $this>getMock('CgaUserChecker1', array('execute'));
96.
// Configure the stub.
97.
$op2->expects($this->any())
98.
->method('execute')
99.
->will($this->returnValue($userMock2));
100.
101.
$this->_cgaUsers->operation(array($op1, $op2));
102.
foreach ($this->_cgaUsers as $user) {
103.
$this->assertTrue($user->confirmed);
104.
$this->assertEquals(2010, $user>anno_registrazione);
105.
106.
}
}
107. }
Listato 4.5 – Esempio di batteria di test unitari per una classe, scritti utilizzando il
framework di test PHPUnit.
4.6 – Installazione del server di Continuous Integration
Il server di Continuous Integration Hudson è stato installato nella stessa macchina su cui
è presente il repository SVN. La scelta di accorpare le due entità anziché tenerle
separate è stata fatta in ottica di una diminuzione di carico della rete LAN, Hudson
infatti ad ogni build scarica per intero i progetti da integrare: data l'entità del traffico si è
preferito passare direttamente per l'hard disk per non influenzare negativamente le
prestazioni ed ottenere un feedback rapido.
Hudson è stato poi configurato in modo da effettuare dei polling verso il repository
SVN ed individuare eventuali cambiamenti: qualora ve ne fossero scarica il codice del
58
4 – Progettazione del cambiamento
progetto e ne effettua la build utilizzando lo stesso script di build degli sviluppatori,
mostrando l'esito delle operazioni sulla propria dashboard.
4.7 – Training del personale
Prima di terminare l'opera di installazione e configurazione dei client e del server di
Continuous Integration si è proceduto con la formazione degli sviluppatori per l'utilizzo
del nuovo ambiente. La Continuous Integration è infatti anzitutto una pratica che
funziona solamente se viene rispettata ed è importante fare in modo che tutti gli
sviluppatori prendano coscienza di quali cambiamenti implicherà nel processo di
sviluppo software e delle relative motivazioni.
4.7.1 – Lezioni frontali
E' stata redatta una presentazione riguardante i temi della Continuous Integration, delle
pratiche su cui si basa e dei problemi che si prefigge di risolvere.
Successivamente si è passato ad una lezione frontale, alla quale hanno partecipato tutti
gli attori coinvolti nello sviluppo software. Sono stati toccati in particolar modo i temi
chiave che presentavano un più immediato beneficio per l'azienda, come ad esempio
l'integrazione e l'automatizzazione del database.
59
4 – Progettazione del cambiamento
4.7.2 – Redazione di documenti operativi
Tutto il materiale visto a lezione è stato messo a disposizione del team di sviluppo e
salvato nel wiki aziendale. E' stato redatto inoltre un documento dai toni informali,
successivamente appeso in bacheca, per non far perdere l'attenzione circa le nuove
tematiche introdotte. Il contenuto del documento è un veloce riassunto delle bestpractises della Continuous Integration, accompagnato da una breve guida che permette
di iniziare a lavorare sin da subito con il nuovo ambiente.
4.7.3 – Post sul corporate blog
E' stato pubblicato un post15 sul corporate blog dell'azienda in cui viene spiegata a
grandi linee la pratica della Continuous Integration e di come sia importante organizzare
il lavoro nel team di sviluppo.
Lo scopo della pubblicazione del post è stato quello di mandare un segnale, sia
all'interno che all'esterno, della presa di coscienza che il successo o l'insuccesso di un
sistema informativo non è solamente decretato dalla tecnologia che utilizza, ma anche
da come questa è organizzata all'interno dell'azienda e dal rispetto delle buone pratiche
di utilizzo.
15 Continuous Integration: quando la pratica va oltre gli strumenti, Giorgio Mandolini, e-xtrategy s.r.l. –
http://www.e-xtrategy.net/2010/06/15/continuous-integration-quando-la-pratica-va-oltre-gli-strumenti
60
5 – Risultati ottenuti
5 – Risultati ottenuti
Questo capitolo descrive i risultati ottenuti a seguito dei cambiamenti introdotti nel
capitolo 4, focalizzando l'attenzione, punto per punto, sui problemi riscontrati nel
capitolo 3. In questa fase verranno espresse infine delle conclusioni sul lavoro svolto ed
eventuali sviluppi futuri.
5.1 Soluzione del problema degli environment eterogenei
L'utilizzo di una convenzione sulle modalità di installazione e configurazione dei
progetti ha portato ad una considerevole diminuzione dei problemi di configurazione
delle applicazioni.
Oltre a ciò lo script di build, grazie alla possibilità di essere parametrizzato, si è
dimostrato una strada molto efficace per uniformare anche client all'apparenza
61
5 – Risultati ottenuti
eterogenei: esso è stato utilizzato infatti sia su macchine Linux che Mac OS, oltre che in
macchine Windows, queste ultime approntate solamente a scopo didattico.
Anche il server di Continuous Integration utilizza il medesimo script di build per
costruire le applicazioni in maniera automatica: in questo modo si è riusciti ad ottenere
la garanzia che tutte le operazioni di installazione e configurazione dei lavori vengono
effettuate in maniera identica e ripetibile su ogni macchina, ed il software presente nel
repository è già pronto per essere rilasciato in produzione.
Quello che inizialmente era un problema di riconfigurazione manuale e dispendiosa è
diventato il lancio di un unico comando da shell: l'unico onere dello sviluppatore è di
fornire eventuali parametri e credenziali di accesso differenti da quelli di default,
qualora sia necessario.
5.2 Soluzione del problema di integrazione del codice
L'utilizzo di test automatici fornisce una rapida indicazione sul funzionamento del
software una volta effettuate delle modifiche ed integrate con il lavoro del resto del
team.
Come imposto dalla pratica non si può inviare codice al repository se questo non è
prima stato verificato da test automatici ed il feedback fornito in seguito dal Continuous
Integration server è una seconda prova sull'avvenuta integrazione.
I benefici dell'introduzione dei test automatici sono evidenti, ma al tempo stesso
62
5 – Risultati ottenuti
l'effettiva messa in atto di questa buona pratica è il compito che richiede più tempo in
azienda.
I test automatici infatti necessitano di tempo per essere scritti e vanno visti come un
investimento: scrivere una volta un test assicura per sempre che una determinata
funzionalità sia testata ed evita il presentarsi due volte dello stesso bug.
Oltre a ciò, l'introduzione di test automatici o pratiche di sviluppo come la Test Driven
Development (TDD), che si basano su di essi, richiedono un'iniziale curva di
apprendimento che durante lo svolgimento del presente lavoro, vista la molteplicità
degli argomenti da trattare, non è potuta essere del tutto affrontata.
I test automatici sono stati comunque introdotti ed implementati in via sperimentale su
alcuni progetti: l'impatto che hanno avuto su di essi è stato giudicato positivo e per
questo l'azienda vede il loro utilizzo a regime come un investimento da fare nel
prossimo futuro.
5.3 Soluzione del problema della visibilità di progetto
La visibilità di progetto ha subito un sensibile miglioramento grazie alla dashboard
fornita dal Continuous Integration server. Lo sviluppatore a colpo d'occhio è in grado di
monitorare lo status di tutti i progetti seguiti dall'azienda e capire subito se su alcuni di
essi vi sono problemi in corso.
63
5 – Risultati ottenuti
Figura 5.1 – Dashboard fornita dal C.I. server Hudson. Il verde indica una build
funzionante mentre il rosso segnala la presenza di problemi.
Figura 5.2 – Dettagli relativi ad un progetto, comprensivi della code coverage dei test
unitari.
64
5 – Risultati ottenuti
Figura 5.3 – Andamento di una build nel tempo.
Figura 5.4 – Dettagli relativi alla copertura del codice.
65
5 – Risultati ottenuti
5.4 Soluzione del problema di integrazione del DB
Il salvataggio del database e degli utenti ad esso adibiti su file posti sotto controllo di
versione è stato il cambiamento che ha portato i benefici più immediati e che per primo
ha incontrato un massiccio utilizzo da parte di tutti gli sviluppatori.
L'automatizzazione delle procedure di cancellazione e reimportazione del database ad
ogni build ha portato alla completa sincronizzazione dei dati e delle strutture che a tutti
gli effetti sono trattate come parti del software. Lo sviluppatore deve preoccuparsi
solamente di lanciare i relativi comandi seguiti dalle proprie credenziali di accesso al
proprio DBMS locale: tutto il resto è interamente gestito dallo script di build.
Figura 5.5 – Schermata con i risultati dell'esecuzione del target build per il setup del
database di un progetto.
66
5 – Risultati ottenuti
Figura 5.6 – Schermata con i risultati dell'esecuzione del target make-sql per il salvataggio
in locale del database di un progetto.
5.5 Soluzione del problema di ingresso al progetto
Anche il problema di ingresso al progetto è stato mitigato grazie all'utilizzo di procedure
automatiche che rendono l'installazione e la configurazione del software un processo
molto più rapido rispetto alla modalità di lavoro precedente.
C'è ancora margine di miglioramento: il setup del file degli host è ancora manuale per i
client Mac OS.
67
5 – Risultati ottenuti
Figura 5.7 – Installazione di un progetto in locale, tramite l'utilizzo dello script bash
install.sh.
Una miglioria ottenuta, che esula dalla Continuous Integration è stata la configurazione
della stessa macchina contenente il repository SVN anche come “client di emergenza”.
In essa sono infatti già presenti tutte le applicazioni web correttamente funzionanti:
qualora si avesse la necessità di dover effettuare piccole modifiche su una di esse,
basterà accedervi direttamente, con la stessa modalità di sviluppo degli altri client;
sebbene questa situazione dovrebbe presentarsi in via del tutto eccezionale, è comunque
rispettosa della pratica della Continuous Integration.
E' da segnalare, infine, che il file degli host va aggiornato una sola volta all'avvio del
progetto: anche quando questo non viene più seguito dallo sviluppatore e rimosso
dall'hard disk della propria workstation è consigliabile non eliminarne l'entry da tale
68
5 – Risultati ottenuti
file. In questo modo, a fronte di pochi kilobyte di informazione, si risparmieranno
preziosi minuti di tempo nella sua configurazione in caso di necessità di riaprire il
lavoro, mentre per tutto il resto entra in gioco lo script di build.
5.6 Soluzione del problema delle demo
Il problema delle demo è stato risolto con successo: grazie al Continuous Integration
server che si occupa di
reperire
periodicamente una versione
aggiornata
dell'applicazione web, è sempre possibile vederne una copia in anteprima.
E' sufficiente dare accesso ai clienti alla URL prestabilita.
5.7 Futuri sviluppi: automatizzare il deploy
Per quanto riguarda il deploy delle applicazioni si è preferito non procedere con
l'automatizzazione delle operazioni. Il deploy è infatti un compito molto delicato, che di
volta in volta potrebbe essere diverso.
Non è pensabile di distruggere interamente l'applicazione in produzione per sostituirla
con la nuova versione perché verrebbero inevitabilmente persi tutti i dati prodotti dagli
utenti durante il periodo di normale funzionamento.
E' preferibile una strada di tipo incrementale, in cui gli interventi di pubblicazione dei
files siano mirati e posti sotto rigido controllo umano: è necessario inviare al server di
69
5 – Risultati ottenuti
produzione solamente lo stretto necessario, impiegando il minor tempo possibile e
preservando tutti i dati finora prodotti.
Sarebbe comunque interessante proseguire lo studio di metodi di automazione che
rientrino anche in quest'ultimo ambito per chiudere il cerchio dello sviluppo e giungere
così alla creazione di un ambiente automatizzato in ogni sua parte.
70
6 – Bibliografia
6 – Bibliografia
6.1 – Letteratura
Paul M. Duvall, Steve Matyas, Andrew Glover - Continuous Integration: Improving
Software Quality and Reducing Risk, http://www.integratebutton.com/, AddisonWesley Professional 2007
Extreme programming – Integrate Often,
http://www.extremeprogramming.org/rules/integrateoften.html.
Martin Fowler – Continuous Integration,
http://martinfowler.com/articles/continuousIntegration.html, 2006.
Kent Beck – Test Driven Development: By Example, Addison-Wesley Professional
2002.
71
6 – Bibliografia
Kent Beck, Cynthia Andres – Extreme Programming Explained: Embrace Change (2nd
Edition), Addison-Wesley Professional, 2004.
6.2 – Risorse e strumenti
Extreme Programming – http://www.extremeprogramming.org/ .
Martin Fowler – http://martinfowler.com/.
Kent Beck – http://www.threeriversinstitute.org/Kent Beck.htm.
Apache Subversion – http://subversion.apache.org/.
Apache HTTP Server Project – http://httpd.apache.org/ .
Oracle MySQL – http://www.mysql.com/ .
Zend Server – http://www.zend.com/products/server/ .
Phing – http://www.phing.info/.
Selenium - Web Browser Automation – http://seleniumhq.org/ .
Hudson Continuous Integration – http://hudson-ci.org/ .
Continuous Integration: quando la pratica va oltre gli strumenti, Giorgio Mandolini,
e-xtrategy s.r.l. – http://www.e-xtrategy.net/2010/06/15/continuous-integrationquando-la-pratica-va-oltre-gli-strumenti, 2010.
Continuous Integration: un'introduzione, Giorgio Mandolini, HTML.it –
http://php.html.it/articoli/leggi/3905/continuous-integration-unintroduzione/, 2012.
72
Ringraziamenti
Ringraziamenti
Molto probabilmente questa sarà l'unica parte che verrà letta dai miei amici, alcuni dei
quali,senza fare nomi, non ci prendono con le H su Facebook, dubito che siano
interessati ai miei tecnicismi , ma sono miei amici anche per questo :D
Con queste ultime ultime righe si chiude un importante capitolo della mia vita, qualcosa
di nuovo mi attende: è li fuori e non aspetta altro che essere vissuto. Chi mi conosce sa
quanto abbia lottato per arrivare a questa svolta, quanto la desiderassi e di quanto ne
avessi bisogno, anche in quei momenti in cui ho veramente pensato di arrendermi.
Voglio ringraziare innanzitutto la mia famiglia, che mi ha supportato e sopportato
sempre, ed alla quale devo tutto. All'amore di mio padre, mia madre e mio fratello. Un
pensiero ai miei nonni, a nonno Remo che mi guarda da lassù e nonna Amalia, che ogni
volta che passavo un esame ripeteva “Toccherà mettese el cappello”.
Non è facile trovare persone che credono in te anche quando tu stesso hai smesso di
Ringraziamenti
farlo, per questo dedico un ringraziamento speciale ad e-xtrategy, che ha saputo capirmi
in uno dei periodi più difficili della mia vita, continuando a darmi fiducia: forse Lorenzo
non dimenticherà un nostro colloquio, alquanto poco professionale :-)
Al pazzo fine estate 2011, ed alle nuove persone che mi ha portato. Michela, Lara, Luca:
parte del sorriso che oggi ho sulle labbra è anche grazie a voi :-)
A Mauro, perché è l'Amico, con la A maiuscola. Potrei scrivere pagine e pagine su di
lui, le nostre avventure ed aneddoti, ma credo che gliele riferirò personalmente, magari
davanti una buona birra.
Ai miei compagni di studi Gilberto e Filippo, amici e confidenti di scleri universitari e
vita privata. Alla nonchalance (ti fischiano le orecchie Lele ?).
A tutti i miei amici storici, non vi posso elencare perché finirei col dimenticare
qualcuno, ma credetemi, siete tutti quanti nei miei pensieri.
Alla mia amica Alice per le nostre chiacchierate da sognatori.
A te ho già dedicato più di un anno di vuoto nel mio libretto, direi che può bastare :D
Vabbé, è giunto il momento di andare in copisteria e stampare queste pagine, il mio
vicino mi sta mettendo fretta (eh Lele ?) e non ha torto: tutta 'sta neve sta rendendo le
cose non troppo semplici, meglio sbrigarsi finché possiamo.
Ah, dimenticavo una cosa importantissima!
Ora mamma posso dirtelo: ho scelto informatica perché almeno mi compravi il
computer :-)