MODELLI E METODI PER LA QUALITÀ DEL SOFTWARE Gruppo: MMS Progetto: Traccar Realizzato da Montemurro Andrea 681902 ITPS Corso B [email protected] Moramarco Francesco 676253 ITPS-Corso B [email protected] Soprano Francesco 683676 ITPS Corso B [email protected] Descrizione del progetto Traccar è un sistema di tracciamento GPS che consente di monitorare più di 1500 modelli di tracker GPS con più di 170 protocolli differenti, è open source ed è possibile installarlo su un server privato. Traccar include un'interfaccia-web based con interfaccia sia desktop che mobile-friendly, protetta da credenziali di accesso, e tramite la quale è possibile configurare e visionare in diretta la posizione dei tracker gps sulla mappa o è possibile consultarne la cronologia. Sono inoltre disponibili anche client per dispositivi Android ed iOS che permettono di accedere facilmente ed in mobilità al server. Al di fuori della posizione in tempo reale, è anche possibile visionare lo storico dei percorsi, la velocità di marcia, il senso di marcia e tante altre informazioni. Il software Traccar fornisce inoltre notifiche web ed SMS per diversi tipi di allarmi, come eccesso di velocità, mancanza di carburante, violazione del perimetro di geofencing, forti vibrazioni indicative di possibile incidente o tentativo di furto. È possibile utilizzare tracker GPS di diversi marchi, dai modelli low-cost cinesi ai modelli professionali ed è possibile gestire un'ampia varietà di sensori ed informazioni aggiuntive fornite dall'unità GPS. Non vi e limite al numero di tracker GPS che si possono gestire e controllare contemporaneamente. In base alla tipologia di tracker GPS che si decide di usare il sistema può assolvere a diversi compiti: • controllo delle proprie autovetture • controllo della flotta di qualsiasi azienda • controllo di persone anziane e bambini • controllo degli animali domestici È possibile infatti utilizzare qualsiasi tipologia di tracker GPS: • tracker GPS magnetici con la batteria • tracker GPS che si installano facilmente nella porta OBD delle autovetture • tracker GPS che si montano sulle centraline 2 • tracker GPS che si nascondono nei tubolari di motociclette, biciclette, biciclette elettriche • tracker GPS piccolissimi che si possono indossare come collane e collarini È anche possibile controllare il GPS di un qualsiasi smartphone in modo da controllarne gli spostamenti. Tutto questo in totale sicurezza, senza dover cedere a terzi dati così sensibili e senza dover pagare abbonamenti mensili. Tutto sotto il proprio controllo. Un sistema di geolocalizzazione realizzato con un server Linux e Traccar permette di usufruire della migliore tecnologia per il tracciamento in tutta sicurezza e senza dover rinunciare alla propria privacy cedendo a terzi uno dei dati più privati, la nostra posizione. Un sistema così fatto non ha limiti di scalabilità e di compatibilità. È possibile installare il server ovunque si voglia, in un'abitazione o in un ufficio. È possibile creare un account per chiunque si voglia, per tutti i componenti della propria famiglia, per i propri collaboratori, per i propri dipendenti, per i propri amici. Ognuno può accedere solo ed esclusivamente al proprio account utilizzando le proprie credenziali. È possibile associare ad ogni account uno o più tracker GPS. In questo modo c'è chi può controllare e visionare solo il proprio tracker GPS e c'è chi può controllare e visionare tutti i tracker GPS. È possibile accedere al proprio account da qualsiasi parte del mondo, basta una semplice connessione internet. È possibile utilizzare quanti tracker GPS si vogliono. È possibile utilizzare tracker GPS di diverse tipologie e di diverse marche. Link al progetto GitHub: https://github.com/traccar/traccar 3 Report iniziale Figura 1 Prima analisi sonarqube Figura 2 Risultato test maven iniziale La prima analisi svolta mediante il tool Sonarqube ha evidenziato le seguenti problematiche: n. 58 Bugs, di cui: o n. 25 di severity minor o n. 27 di severity major o n. 6 di severity blocker n. 3 vulnerabilities, di cui: o n. 1 minor o n. 2 blocker 4 n. 2560 code smells, di cui: o n. 48 blocker o n. 446 critical o n. 589 major o n. 1465 minor o n. 12 info L’effort stimato da Sonarqube con questa prima analisi è di 64 giorni di debito, calcolati in 8 ore lavorative l’uno, per un totale 512 ore. ACTION PLAN 1 Il target prefissato da raggiungere per completare l’action plan è il seguente: • Bugs A (0) • Vulnerabilities A (0) • Technical Debt 7 d La scelta è stata di creare un unico action plan, scandendo le issues da risolvere per tipologia, nel rispettivo ordine: 1. Bugs 2. Vulnerabilities 3. Code Smells L’esecuzione del piano risolutivo è stata avviata il giorno 22 dicembre 2019 e conclusosi il giorno 9 gennaio 2020. Di seguito l’elenco completo delle issue che compongono l’action plan 1. 5 MMS - Segnalazioni # Tracker Stato Priorità Autore Oggetto Assegnato a Aggiornato Inizio Scadenza Segnalazioni % completato correlate 36563 To-Do Closed Immediate Andrea S2095 Resources should be closed Andrea 2020-01-09 2019-12-22 2019-12-23 100 Montemurro Montemurro 17:18 36522 To-Do Closed High Andrea S2142 "InterruptedException" should not Andrea 2020-01-09 2019-12-22 2019-12-24 100 Montemurro be ignored Montemurro 17:21 36521 To-Do Closed High Francesco S2259 Null pointers should not be Francesco 2020-01-09 2019-12-22 2019-12-25 100 Moramarco dereferenced Moramarco 17:26 36518 To-Do Closed Normal Francesco Pio S2184 Math operands should be cast Francesco Pio 2020-01-10 2019-12-22 2019-12-22 100 Soprano before assignment Soprano 11:09 36517 To-Do In Progress Immediate Francesco Pio Action Plan 1 Francesco Pio 2020-01-10 2019-12-22 2020-01-11 100 Soprano Soprano 13:27 36585 To-Do Closed Immediate Andrea S2068 Credentials should not be Andrea 2020-01-09 2019-12-23 2019-12-23 100 Montemurro hard-coded Montemurro 17:19 36584 To-Do Closed High Andrea S2583 Conditionally executed blocks Andrea 2020-01-09 2019-12-23 2019-12-23 100 Montemurro should be reachable Montemurro 17:22 36578 To-Do Closed High Francesco Pio S1192 String literals should not be Francesco Pio 2020-01-09 2019-12-23 2019-12-27 100 Soprano duplicated Soprano 17:29 36577 To-Do Closed Normal Francesco S1148 Throwable.printStackTrace(...) Francesco 2020-01-09 2019-12-23 2019-12-24 100 Moramarco should not be called Moramarco 17:23 36576 To-Do Closed High Francesco S1862 Related "if/else if" statements Francesco 2020-01-09 2019-12-23 2019-12-24 100 Moramarco should not have the same condition Moramarco 17:24 36575 To-Do Closed High Francesco S2111 "BigDecimal(double)" should not be Francesco 2020-01-09 2019-12-23 2019-12-24 100 Moramarco used Moramarco 17:25 36665 To-Do Closed High Andrea S00112 Generic exceptions should never Andrea 2020-01-10 2019-12-26 2019-12-27 100 Montemurro be thrown Montemurro 13:13 37753 To-Do Closed High Andrea S3027 String function use should be Andrea 2020-01-09 2019-12-27 2019-12-28 100 Montemurro optimized for single characters Montemurro 17:33 37747 To-Do Closed Normal Andrea S1659 Multiple variables should not be Andrea 2020-01-10 2019-12-27 2019-12-28 100 Montemurro declared on the same line Montemurro 13:19 37689 To-Do Closed Normal Francesco CallToDeprecatedMethod "@Deprecated" Francesco 2020-01-09 2019-12-27 2020-01-04 100 Moramarco code should not be used Moramarco 17:48 37625 To-Do Closed Urgent Francesco S2178 Short-circuit logic should be used in Francesco 2019-12-27 2019-12-27 2019-12-29 100 Moramarco boolean contexts Moramarco 18:50 37619 To-Do Closed High Francesco Pio S3776 Cognitive Complexity of methods Francesco Pio 2020-01-10 2019-12-27 2020-01-08 100 Soprano should not be too high Soprano 13:06 37599 To-Do Closed High Francesco S1149 Synchronized classes Vector, Francesco 2019-12-27 2019-12-27 2019-12-29 100 Moramarco Hashtable, Stack and StringBuffer should Moramarco 18:49 not be used 6 # Tracker Stato Priorità Autore Oggetto Assegnato a Aggiornato Inizio Scadenza Segnalazioni % completato correlate 37552 To-Do Closed High Andrea S3457 Printf-style format strings should be Andrea 2020-01-10 2019-12-27 2019-12-28 100 Montemurro used correctly Montemurro 13:13 37477 To-Do Closed Normal Francesco S00116 Field names should comply with a Francesco 2020-01-03 2019-12-27 2020-01-05 100 Moramarco naming convention Moramarco 12:45 41028 To-Do Rejected High Francesco S2629 "Preconditions" and logging Francesco Pio 2020-01-10 2019-12-28 2020-01-09 100 Moramarco arguments should not require evaluation Soprano 13:09 37881 To-Do Closed Low Francesco Pio S1301 "switch" statements should have at Francesco Pio 2019-12-28 2019-12-28 2019-12-28 100 Soprano least 3 "case" clauses Soprano 19:46 37880 To-Do Closed Normal Francesco Pio LabelsShouldNotBeUsedCheck Francesco Pio 2019-12-28 2019-12-28 2019-12-28 100 Soprano Soprano 19:15 37879 To-Do Closed Low Francesco Pio S1450 Private fields only used as local Francesco Pio 2020-01-09 2019-12-28 2019-12-28 100 Soprano variables in methods should become local Soprano 17:39 variables 37878 To-Do Closed Normal Francesco Pio HiddenFieldCheck Local variables should Francesco Pio 2020-01-10 2019-12-28 2019-12-28 100 Soprano not shadow class fields Soprano 13:21 37877 To-Do Closed High Andrea S2629 "Preconditions" and logging Andrea 2020-01-10 2019-12-28 2020-01-09 100 Montemurro arguments should not require evaluation Montemurro 13:09 37871 To-Do Closed Normal Francesco Pio S1168 Empty arrays and collections should Francesco Pio 2019-12-28 2019-12-28 2019-12-29 100 Soprano be returned instead of null Soprano 18:15 37868 To-Do Closed High Francesco Pio S2447 Null should not be returned from a Francesco Pio 2020-01-09 2019-12-28 2019-12-28 100 Soprano "Boolean" method Soprano 17:37 37822 To-Do Closed Urgent Francesco Pio S128 Switch cases should end with an Francesco Pio 2020-01-09 2019-12-28 100 Soprano unconditional "break" statement Soprano 17:35 37757 To-Do Closed Normal Andrea HiddenFieldCheck Local variables should Andrea 2020-01-10 2019-12-28 2019-12-28 100 Montemurro not shadow class fields Montemurro 13:21 37892 To-Do Closed Low Francesco Pio S1488 Local variables should not be Francesco Pio 2020-01-07 2019-12-29 2019-12-29 100 Soprano declared and then immediately returned or Soprano 18:21 thrown 37891 To-Do Closed High Francesco Pio S1066 Collapsible "if" statements should be Francesco Pio 2020-01-09 2019-12-29 2019-12-29 100 Soprano merged Soprano 17:44 37890 To-Do Closed Normal Francesco Pio S3972 Conditionals should start on new Francesco Pio 2020-01-09 2019-12-29 2019-12-29 100 Soprano lines Soprano 17:43 37888 To-Do Closed High Andrea S3415 Assertion arguments should be Andrea 2020-01-09 2019-12-29 2019-12-29 100 Montemurro passed in the correct order Montemurro 17:43 37883 To-Do Closed Urgent Andrea S1186 Methods should not be empty Andrea 2020-01-10 2019-12-29 2019-12-29 100 Montemurro Montemurro 13:27 37913 To-Do Closed High Francesco S1068 Unused "private" fields should be Francesco 2020-01-09 2019-12-30 2019-12-30 100 Moramarco removed Moramarco 17:45 38899 To-Do Closed High Andrea S1172 Unused method parameters should Andrea 2020-01-09 2020-01-01 2020-01-01 100 Montemurro be removed Montemurro 17:45 7 # Tracker Stato Priorità Autore Oggetto Assegnato a Aggiornato Inizio Scadenza Segnalazioni % completato correlate 38933 To-Do Closed Normal Andrea S1604 Anonymous inner classes Andrea 2020-01-09 2020-01-02 2020-01-02 100 Montemurro containing only one method should become Montemurro 17:47 lambdas 38932 To-Do Closed Normal Andrea S1610 Abstract classes without fields Andrea 2020-01-09 2020-01-02 2020-01-02 100 Montemurro should be converted to interfaces Montemurro 17:46 39453 To-Do Closed Normal Francesco Pio S1479 "switch" statements should not have Francesco Pio 2020-01-04 2020-01-04 2020-01-04 100 Soprano too many "case" clauses Soprano 19:38 39424 To-Do Closed Low Francesco Pio S3878 Arrays should not be created for Francesco Pio 2020-01-09 2020-01-04 2020-01-04 100 Soprano varargs parameters Soprano 17:52 39370 To-Do Closed Normal Francesco Pio S2589 Boolean expressions should not be Francesco Pio 2020-01-10 2020-01-04 2020-01-04 100 Soprano gratuitous Soprano 13:24 39712 To-Do Closed High Francesco Pio SwitchLastCaseIsDefaultCheck Francesco Pio 2020-01-09 2020-01-05 2020-01-05 100 Soprano statements should have "default" clauses Soprano 17:59 39709 To-Do Closed Normal Francesco Pio S1854 Dead stores should be removed Francesco Pio 2020-01-10 2020-01-05 2020-01-05 100 Soprano Soprano 13:16 39703 To-Do Closed Normal Francesco Pio S1700 A field should not duplicate the Francesco Pio 2020-01-05 2020-01-05 2020-01-05 100 Soprano name of its containing class Soprano 17:46 39699 To-Do Closed Low Francesco Pio S1602 Lamdbas containing only one Francesco Pio 2020-01-09 2020-01-05 2020-01-05 100 Soprano statement should not nest this statement in Soprano 17:57 a block 39557 To-Do Closed Low Francesco Pio S1126 Return of boolean expressions Francesco Pio 2020-01-05 2020-01-05 2020-01-05 100 Soprano should not be wrapped into an "if-then-else" Soprano 11:50 statement 39510 To-Do Closed Normal Francesco Pio ForLoopCounterChangedCheck "for" loop Francesco Pio 2020-01-09 2020-01-05 2020-01-05 100 Soprano stop conditions should be invariant Soprano 17:56 39499 To-Do Closed Low Francesco Pio UselessImportCheck Useless imports Francesco Pio 2020-01-10 2020-01-05 2020-01-05 100 Soprano should be removed Soprano 13:18 37959 To-Do Closed Low Francesco UselessImportCheck Useless imports Francesco 2020-01-10 2020-01-05 2020-01-05 100 Moramarco should be removed Moramarco 13:18 37821 To-Do Closed Normal Andrea S1854 Dead stores should be removed Andrea 2020-01-10 2020-01-05 2020-01-05 100 Montemurro Montemurro 13:16 40379 To-Do Closed High Francesco MaximumInheritanceDepth Inheritance tree 2020-01-10 2020-01-07 2020-01-09 100 Moramarco of classes should not be too deep 13:01 40378 To-Do Closed High Francesco S1607 Tests should not be ignored Francesco 2020-01-09 2020-01-07 2020-01-09 100 Moramarco Moramarco 10:30 40377 To-Do Closed High Francesco S1479 "switch" statements should not have Francesco Pio 2020-01-09 2020-01-07 2020-01-09 100 Moramarco too many "case" clauses Soprano 18:05 40376 To-Do Closed High Francesco S2975 "clone" should not be overridden Francesco Pio 2020-01-09 2020-01-07 2020-01-09 100 Moramarco Soprano 18:03 8 # Tracker Stato Priorità Autore Oggetto Assegnato a Aggiornato Inizio Scadenza Segnalazioni % completato correlate 40375 To-Do Closed High Francesco S2925 "Thread.sleep" should not be used Francesco Pio 2020-01-07 2020-01-07 2020-01-09 100 Moramarco in tests Soprano 22:34 40374 To-Do Closed High Francesco S2274 "Object.wait(...)" and Francesco 2020-01-08 2020-01-07 2020-01-09 100 Moramarco "Condition.await(...)" should be called Moramarco 12:33 inside a "while" loop 40373 To-Do Closed Normal Francesco S3824 "Map.get" and value test should be Francesco Pio 2020-01-09 2020-01-07 2020-01-09 100 Moramarco replaced with single method call Soprano 18:04 40372 To-Do Closed High Francesco S2187 TestCases should contain tests Francesco 2020-01-09 2020-01-07 2020-01-09 100 Moramarco Moramarco 18:06 40371 To-Do Closed Low Francesco S135 Loops should not contain more than a Francesco 2020-01-07 2020-01-07 2020-01-09 100 Moramarco single "break" or "continue" statement Moramarco 21:03 40370 To-Do Closed Low Francesco S1125 Boolean literals should not be Francesco 2020-01-07 2020-01-07 2020-01-07 100 Moramarco redundant Moramarco 19:14 40369 To-Do Closed High Francesco S1452 Generic wildcard types should not Francesco 2020-01-09 2020-01-07 2020-01-07 100 Moramarco be used in return parameters Moramarco 18:02 40368 To-Do Closed Low Francesco Pio S1319 Declarations should use Java Francesco Pio 2020-01-09 2020-01-07 2020-01-07 100 Soprano collection interfaces such as "List" rather Soprano 18:02 than specific implementation classes such as "LinkedList" 40367 To-Do Closed High Francesco S1161 "@Override" should be used on Francesco 2020-01-07 2020-01-07 2020-01-07 100 Moramarco overriding and implementing methods Moramarco 18:29 39963 To-Do Closed High Andrea DuplicatedBlocks Source files should not Andrea 2020-01-09 2020-01-07 2020-01-11 100 Montemurro have any duplicated blocks Montemurro 18:05 39962 To-Do Closed High Andrea CommentedOutCodeLine Sections of code Andrea 2020-01-09 2020-01-07 2020-01-07 100 Montemurro should not be commented out Montemurro 17:59 41031 To-Do Closed High Francesco S2681 Multiline blocks should be enclosed Francesco Pio 2020-01-09 2020-01-09 2020-01-09 100 Moramarco in curly braces Soprano 14:25 41019 To-Do Closed Low Francesco Pio RedundantThrowsDeclarationCheck Francesco Pio 2020-01-10 2020-01-09 2020-01-09 100 Soprano "throws" declarations should not be Soprano 13:10 superfluous 41017 To-Do Closed High Francesco S00107 Methods should not have too many Andrea 2020-01-09 2020-01-09 2020-01-09 100 Moramarco parameters Montemurro 16:46 41014 To-Do Closed Low Francesco Pio S1182 Classes that override "clone" should Francesco Pio 2020-01-09 2020-01-09 2020-01-09 100 Soprano be "Cloneable" and call "super.clone()" Soprano 18:09 41012 To-Do Closed Low Francesco S1481 Unused local variables should be Francesco 2020-01-09 2020-01-09 2020-01-09 100 Moramarco removed Moramarco 12:23 40996 To-Do Closed High Francesco Pio S3973 A conditionally executed single line Francesco Pio 2020-01-09 2020-01-09 2020-01-09 100 Soprano should be denoted by indentation Soprano 18:08 9 # Tracker Stato Priorità Autore Oggetto Assegnato a Aggiornato Inizio Scadenza Segnalazioni % completato correlate 40987 To-Do Closed High Francesco Pio S2129 Constructors should not be used to Francesco Pio 2020-01-09 2020-01-09 2020-01-09 100 Soprano instantiate "String", "BigInteger", Soprano 18:07 "BigDecimal" and primitive-wrapper classes 40984 To-Do Closed Low Francesco S3626 Jump statements should not be Andrea 2020-01-09 2020-01-09 2020-01-09 100 Moramarco redundant Montemurro 18:12 40981 To-Do Closed Low Francesco S1199 Nested code blocks should not be Andrea 2020-01-09 2020-01-09 2020-01-09 100 Moramarco used Montemurro 18:13 40979 To-Do Closed Low Francesco Pio S00100 Method names should comply with Francesco Pio 2020-01-09 2020-01-09 2020-01-09 100 Soprano a naming convention Soprano 11:47 40973 To-Do Closed Urgent Francesco Pio S1845 Methods and field names should not Francesco Pio 2020-01-09 2020-01-09 2020-01-09 100 Soprano be the same or differ only by capitalization Soprano 18:07 37887 To-Do Closed Low Andrea RedundantThrowsDeclarationCheck Andrea 2020-01-10 2020-01-09 2020-01-09 100 Montemurro "throws" declarations should not be Montemurro 13:10 superfluous 10 Figura 3 Gantt di pianificazione (unità di misura in giorni) 11 La correzione di tutti i bugs e vulnerabilities è stata il completata il giorno 24 dicembre 2019. Contestualmente, è stata avviata la correzione dei code smells. Figura 4 Situazione piano risolutivo del 26/12/2019 Dall’analisi di Sonarcloud si evince una notevole differenza in termini di Technical Debt: 64 giorni Sonarqube contro i 37 giorni di Sonarcloud. Figura 5 Analisi Sonarcloud 12 Le differenze rilevate da Sonarqube sono dovute alle issues relative al file OmnicommMessageOuterClass.java, non rilevate da Sonacloud. Questo file non è modificabile ed è rigenerato automaticamente dal buffer compiler OmnicommMessage.proto, come si evince nei commenti presenti nel file. Questo ci ha portato a rivalutare il nostro piano d’esecuzione. Abbiamo così segnato come won’t fix 1592 code smells, riducendo l’effort di 26 giorni (208 ore lavorative). Figura 6 Situazione piano risolutivo dopo l'esclusione del file OmnicommMessageOuterClass.java Successivamente, alcuni code smells sono stati segnati come falsi positivi. Essi sono i seguenti: • n.12 S00112 - Generic exceptions should never be thrown o L’eccezione è già correttamente gestita • n. 3 S2447 - Null should not be returned from a "Boolean" method o Il controllo sul valore null è già gestito dove il metodo è Invocato • n. 1 S1191 - Classes from "sun.*" packages should not be used o Non siamo riusciti a trovare classi nelle Api Java che svolgessero le stesse funzionalità Sono stati invece segnalati come won’t fix i seguenti code smells: • n. 2 S3776 - Cognitive Complexity of methods should not be too high o Non è stato possibile diminuire ulteriormente la complessità 13 • n.13 MaximumInerithanceDepth - Inheritance tree of classes should not be too deep o Data la struttura complessa del progetto non è possibile modificare la gerarchia delle classi Inoltre, si è persa la tracciabilità dei seguenti code smells rilevati durante la prima analisi: 1. S1141 - Try-catch blocks should not be nested 2. S1871 - Two branches in a conditional structure should not have exactly the same implementation 3. MissingDeprecatedCheck - Deprecated elements should have both the annotation and the Javadoc tag 4. S1133 - Deprecated code should be removed Alcuni di essi potrebbero essere stati fixati durante la risoluzione di altre issue in qualche modo collegate. Ad esempio, la issue S1133 potrebbe essere stata involontariamente risolta durante la risoluzione della issue CallToDeprecatedMethod, dove contestualmente alle modifiche necessarie a richiamare metodi non deprecati, i metodi deprecati siano stati eliminati. Di altri invece, potrebbe esserne stata persa la tracciabilità a causa dei malfunzionanti della piattaforma Redmine o della mancata comunicazione tra i membri del team e creazione della relativa issue sulla piattaforma. 14 Grafici tempi di effort Figura 7 Istogramma con effort pianificato e effettivo per Bugs Figura 8 Delta effort pianificato/effettivo per Bugs Dagli istogrammi si può notare come la risoluzione dei bugs rientra nei tempi stimati da SonarQube, eccetto per l’ issue “S2095 Resources should be closed”, per il quale si è impiegato quasi 3 ore in più del tempo previsto. 15 Figura 9 Istogramma con effort pianificato e effettivo per Vulnerabilities Figura 10 Delta effort pianificato/effettivo per Vulnerabilities Entrambe le vulnerabilities sono state eliminate in anticipo rispetto ai tempi previsti, con un guadagno totale di circa 2 ore. 16 Figura 11 Istogramma con effort pianificato e effettivo per Code Smells 17 Figura 12 Delta effort pianificato/effettivo per Code Smells 18 In generale anche i code smells sono stati risolti entro i tempi prestabiliti (anche con molto anticipo) ad eccezione di 3: 1. S1172 - Unused method parameters should be removed 2. S3776 - Cognitive Complexity of methods should not be too high 3. S00112 - Generic exceptions should never be thrown Bisogna notare che i grafici mostrano solo i problemi su cui si è realmente lavorato modificando il sorgente, quindi sono escluse tutte le issues risolte come falsi positivi e won’t fix. La correzione di tutte le issues che compongono l’action plan, e di conseguenza del piano esecutivo, è terminata il 9 gennaio 2020. Durante tale processo, si sono verificati casi in cui il metodo risolutivo applicato ha portato alla generazione di altri bug (uno solo ed in unica occasione) e code smells. I nuovi code smells e bugs non hanno particolarmente influenzato il piano esecutivo, per cui sono stati inglobati all’interno dello stesso action plan 1. Per questo motivo sulla piattaforma Redmine sono presenti delle issue “doppioni” (con lo stesso oggetto), che sono state registrate come sotto attività della prima issue registrata con lo stesso squid. Per semplicità, alcune delle issues risolte come false positive e won’t fix non state caricate sulla piattaforma Redmine, in quanto il tempo effettivo di risoluzione sarebbe stato pari a 0 e i sorgenti non modificati. Ciò avrebbe potuto provocare delle anomalie tra la stima di effort e l’effettivo tempo di esecuzione. La risoluzione di molti code smells è stata agevolata dall’utilizzo dell’IDE IntelliJ IDEA, il quale fornisce ottimi suggerimenti per la risoluzione delle tematiche più generali, come ad esempio la convenzione Java per i nomi di metodi e variabili. Di particolare aiuto sono state le possibilità di refactor e rename a disposizione. Il refactor, mediante la funzione di extract method è stato ampiamente utilizzato per la risoluzione delle issues relative alla complessità cognitiva. In linea generale, ciascun membro del team ha scelto l’issue da risolvere senza particolari prerogative o criteri, ma semplicemente rispettando il criterio di tipologia definito all’inizio dell’action plan. Scelta la issue, si sono poi seguiti i seguenti passi: 1. Notifica ai membri del gruppo dell’issue scelta 2. Creazione della segnalazione su redmine, con oggetto contenete lo squid e il nome dell’issue e completa di informazioni relative a: data di inizio, data di scadenza, tempo stimato (fornito da Sonarqube), attività principale, priorità, membro del team a cui è 19 assegnato e descrizione contenente l’elenco dei file in cui è presente tale problematica. 3. Modifica del/dei sorgente/i relativi 4. Verifica dell’attuata correzione mediante: a. Maven test b. Analisi con sonarqube 5. Commit del/dei sorgente/i modificato/i, specificando il tag relativo all’issue risolta e il tempo impiegato (@references #IDISSUE @orehminutim) 6. Chiusura della issue su Redmine 7. Notifica ai membri del gruppo dell’avvenuta correzione Si è resa necessaria un’unica operazione di revert su un file (Tk103FrameDecoder.java) il 04/01/2020, relativo all’issue Cognitive Complexity of methods should not be too high (S3776) in quanto la modifica effettuata portava al fallimento di alcuni test di regressione. 20 Figura 13 Gantt finale di esecuzione 21 Report Finale Figura 14 Assessment di qualità dopo lo svolgimento dell’Action Plan 1 Figura 15 Andamento complessivo del piano esecutivo 22 Figura 16 Risultato test maven finale Al termine dell’Action Plan 1, non solo si è raggiunto il target prefissato, ma si è proseguito nella risoluzione delle issues restanti. Considerazioni finali La sola esecuzione del Action plan 1 è bastata per raggiungere i parametri di qualità richiesti, pertanto non è stato necessario stipulare la pianificazione di un ulteriore piano. Ciò è stato possibile grazie a ritmi di lavoro molto sostenuti da parte di tutti e tre i membri del team, nonché alla efficacia del combinato utilizzo dei diversi strumenti di lavoro. Su tutti, la piattaforma Redmine si è rivelata un utile alleato alla persecuzione degli obbiettivi entro i termini previsti. Infatti, come noto, ci sono stati giorni in cui la piattaforma ha cessato di funzionare e, come riscontrato anche dai grafici di andamento di risoluzione dei problemi, l’attività ha subito in alcuni momenti un rallentamento. Tale rallentamento è riscontrabile soprattutto per la issue relativa allo squid: S3776 sulla Complessità Cognitiva. Tale issue richiedeva infatti il refactor su numerosi classi di file distinti del progetto, pertanto per evitare problemi di tracciabilità è stato richiesto una grande collaborazione tra i tre sviluppatori anche tramite l’utilizzo di altre piattaforme. Per ovviare a questo problema, per un ipotetico futuro progetto si potrà contemplare l’adozione di un server web remoto sul quale sfruttare lo strumento di analisi del codice in maniera centralizzata, in modo da avere un’analisi sui problemi da risolvere comunque “allineata” anche nel caso in cui il repository (nel nostro caso SubVersion in RedMine) non funzionasse. Durante l’esecuzione dell’action plan si è notata generalmente una sovrastima del tempo di effort da parte di Sonar. Solo poche issue sono state chiuse in ritardo, come la già citata 23 issue avente S3776 come squid, sia per problemi inerenti alla piattaforma RedMine sia per effettive difficoltà da parte dei componenti del gruppo nelle fasi iniziali di apertura della issue. Tali problemi sono stati superati anche grazie a una migliore praticità presa con l’IDE Intellij che offre numerosi “aiuti” per tali scopi, tornati molto utili durante l’esecuzione della segnalazione relativa ai duplicati di codice, chiusa con un netto anticipo rispetto all’effort stimato (36h vs 10.75 di effettivo lavoro). Nel complesso il gruppo si è ritenuto soddisfatto dell’esperienza fatta con il caso di studio, sia per l’avvenuta consegna nei termini previsti, sia perché grazie a questa attività è stato possibile “toccare con mano” quelle che sono state le tematiche trattate a lezione durante il corso a livello teorico. 24
Enter the password to open this PDF file:
-
-
-
-
-
-
-
-
-
-
-
-