log1000 - ingénierie logicielle automne 2013 examen final · complexité du logiciel.v 1.9 en...

21
LOG1000 - Ingénierie logicielle Automne 2013 Examen final Enseignant : Bram Adams Chargé de lab : Fehmi Jaafar Cet examen comporte 7 questions pour un total de 40 points Pondération : 40% de la note finale Directives : Toute documentation permise, mais aucune calculatrice. Répondez dans votre cahier, pas sur le questionnaire. Re- mettez les deux documents à la fin de l’examen.

Upload: others

Post on 31-May-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 - Ingénierie logicielleAutomne 2013

Examen final

Enseignant : Bram Adams

Chargé de lab : Fehmi Jaafar

Cet examen comporte 7 questions pour un total de 40 points

Pondération : 40% de la note finale

Directives :Toute documentation permise, mais aucune calculatrice.Répondez dans votre cahier, pas sur le questionnaire. Re-mettez les deux documents à la fin de l’examen.

Page 2: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

1 Questions générales (5 points)Pour les 5 questions suivantes, choisissez la réponse qui vous semble être la bonne (0.5 pointpar question).

1.1 Parmi les énoncés suivants concernant le débogage, lequel est inexact ?

a) Les erreurs de fuites de mémoire sont difficilement détectables.

b) RÉPONSE Avec un outil de débogage, la cause d’une erreur peut être trouvée automa-tiquement.

c) L’approche “diviser pour régner” convient bien au contexte de débogage.

d) Les erreurs de syntaxe sont plus faciles à détecter que les erreurs d’exécution.

e) Les tests unitaires peuvent être utiles pour trouver les défauts.

1.2 Quand Glenford J. Myers a dit que « Testing is the process of executing a program with theintent of finding errors », il

a) était en train d’expliquer la différence entre des tests de performance et des unitaires.

b) voulait dire que des testeurs doivent seulement montrer que le système marche dansdes conditions normales, pas essayer de trouver des cas de bord qui ne se manifesterontjamais en réalité.

c) RÉPONSE voulait dire que des testeurs doivent vraiment faire un effort de casser lesystème, pas seulement montrer que le système marche dans des conditions normales.

d) n’avait pas encore essayé de programmer en C++.

e) voulait dire que des tests manuels (en lisant le code) ne sont pas de vrais tests.

1.3 La différence entre la durée de vie et la portée d’une variable est :

a) inexistante, ce sont deux mots pour le même concept.

b) liée au problème des variables allouées sur le tas (“heap”) qui sont encore utilisées dansle code après être désallouées.

c) la différence entre théorie et pratique, c.-à-d. la région maximale de code (par exempleune fonction) où une variable peut exister en théorie versus la région actuelle dans la-quelle elle est utilisée.

d) très petite. La portée est la distance entre chacune des deux références d’une variable,tandis que la durée de vie d’une variable est la distance entre la première et la dernièreréférence d’une variable.

e) RÉPONSE la différence entre pratique et théorie, c.-à-d. la région actuelle dans laquelleune variable est utilisée versus la région maximale de code (par exemple une fonction)où elle peut exister en théorie.

École Polytechnique de Montréal Page 1 de 20 Département de génie informatique et génie logiciel

Page 3: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

1.4 Dans un contexte de gestion de projet, parmi les facteurs suivants, lequel aura le moins derisques d’avoir un impact négatif sur le temps de développement ?

a) La complexité du système à développer.

b) La qualité de l’analyse des exigences.

c) RÉPONSE L’utilisation d’outils logiciels appropriés.

d) Le degré de formalisation de la conception.

e) L’expérience de l’équipe de développement par rapport au domaine applicatif.

1.5. Quel degré de cohésion est illustré par l’exemple de code suivant ?

void prepareReport(Data& data, int report) {switch (report) {

case SALES_REPORT:prepareSalesReport(data);break;

case MANAGEMENT_REPORT:prepareManagementReport(data);break;

case DIRECTION_REPORT:prepareDirectionReport(data);break;

}}

a) Cohésion procédurale.

b) RÉPONSE Cohésion logique.

c) Cohésion fonctionnelle.

d) Cohésion de communication.

e) Cohésion temporelle.

École Polytechnique de Montréal Page 2 de 20 Département de génie informatique et génie logiciel

Page 4: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

Pour chaque énoncé qui suit, dites s’il est vrai ou faux (une bonne réponse vaut 0.5 point et unemauvaise réponse vaut -0.25 point).

1.6 Un test unitaire requiert moins de temps qu’un test d’intégration. V

1.7 Un couplage faible est meilleur qu’une cohésion faible. V

1.8La minimisation de la métrique “span” entraîne une réduction de lacomplexité du logiciel. V

1.9En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés avec des développeurs de même calibre. F

1.10En principe, un test consiste d’un jeu d’arguments d’entrée et une sortieexpectée. V

2 Code de qualité (8 points)Répondez aux 3 questions suivantes (3 points).

a) Pourquoi est-ce que l’on a peur pour « l’érosion de l’abstraction de l’interface aprèsmodifications » ? Illustrez avec un exemple en C++. (1 point) Unrelated methods areadded over time, making interface more complex and less cohesive. Any two versionsof a C++ class interface with methods added, removed, incorrect abstractions used, etc.would work.

b) Donnez un exemple d’héritage en C++ où le principe de Liskov n’est pas suivi. Ensuite,expliquez ce que l’on pourrait faire pour résoudre ce problème et illustrez avec votreexemple. (1 point) Example of inheritance with empty version of one method : pushthat method down to that one subclass instead of in superclass.

c) Quel patron de conception est utilisé aux lignes 57 à 61 du code fourni en annexeB ? Donnez (1) son nom, (2) son but concret dans le contexte de l’exemple, et (3) uneexplication de son implémentation. (1 point) Singleton, one instance of ErrorReporteracross the whole program, using static variable of function.

Pour les deux questions qui suivent, considérez le code fourni en annexe A (5 points).

d) Calculez le span moyen de chacune des variables de la fonction Jedi_ClearPathToSpot(attention : seulement la réponse sera évaluée). Comptez les lignes de commentaires,mais pas les lignes vides ou les lignes contenant seulement { ou }. Si le résultat n’estpas un entier, laissez-le sous forme de fraction simplifiée. Ignorez les variables globalesgi, NPC, STEPSIZE et ENTITYNUM_NONE, alors il reste 10 variables (n’oubliez pasla variable i sur la ligne 39 !). (2,5 points)dest :(5+14+1)/3=20/3impactEntNum :(12)/1=12trace :(4+1+2+1+21+0)/6=29/6 [attention : multiple occurrence on same line not coun-ted]mins :(2+0+28)/3=10start :(29+0+1)/3=10end :(30+0+0)/3=10

École Polytechnique de Montréal Page 3 de 20 Département de génie informatique et génie logiciel

Page 5: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

dir :(18+0+9)/3=9dist :(18+6)/2=12drop :(21+2+5)/3=28/3i :(2)/1=2

e) Comment pourrait-on modifier la déclaration des 10 variables de la question précédenteafin de minimiser le span ? Pour chaque variable, indiquez avant quelle ligne elle devraitêtre déclarée pour obtenir le meilleur span moyen. Traitez chaque cas indépendamment.Exemple : “déclarer x avant la ligne 11”. Il ne faut pas recalculer le span. (2,5 points)dest :(rien à faire)impactEntNum :(rien à faire)trace :(9)mins :(7)start :(42)end :(43)dir :(30)dist :(31)drop :(32)i :(rien à faire)

École Polytechnique de Montréal Page 4 de 20 Département de génie informatique et génie logiciel

Page 6: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

3 Gestion de construction du code (3 points)

0%

10%

20%

30%

40%

50%

60%

70%

80%

90%

100%

2K 8K 32K 128K 512K

Tests système

Intégration

Tests du développeur

Codage et débogage

Conception détaillée

Architecture

FIGURE 1 – Effet de la taille sur les activités de développement.

a) La période de Noël est la période la plus importante pour les producteurs de logicielspour des téléphones intelligents (Android, iOS, etc.). Beaucoup de nouveaux produitssont lancés, dans l’espoir d’attirer l’attention des utilisateurs innocents. L’entrepriseAdams & co. veut mettre en production un nouveau logiciel réveil qui offre une ex-périence incroyable, mais Dr. Adams, le PDG de l’entreprise, a été informé que l’entre-prise Jaafar & co. est en train de préparer un logiciel pareil. Expliquez les deux conceptsd’« estimation » et de « réduction de portée » avec cet exemple. (1 point)Make good estimation of effort required to release on time, if not on time remove unim-portant features to reduce scope, so as to still be the first one on the market.

b) Expliquez pourquoi le fondateur de Amazon (Jeff Bezos) a dit « if a team can’t be fedwith two pizzas, it is too big ». Donnez un exemple. (1 point)Too much communication overhead for training, getting to know what changed, ... . Useformula for combination of 2 out of N to show how communication overhead quicklyskyrockets.

c) Expliquez la Figure 1, c’est-à-dire qu’est-ce que peut-on y observer, et pourquoi ? (1point)Integration/architecture/system tests become more important, since bigger system meansmore teams and hence more subsystems, all of which need to communicate with each

École Polytechnique de Montréal Page 5 de 20 Département de génie informatique et génie logiciel

Page 7: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

other if one does not improve integration/architecture. Also, bigger need to test the wholesystem.

École Polytechnique de Montréal Page 6 de 20 Département de génie informatique et génie logiciel

Page 8: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

4 Débogage (3 points)

FIGURE 2 – Outil #1 (http ://software.opensuse.org/package/screenshot/).

Répondez aux questions suivantes :

a) Quel est le nom et le but de l’outil #1 dans la Figure 2 ? Qu’est-ce qu’un « breakpoint » ?Comment peut-on utiliser un tel « breakpoint » avec une méthode scientifique ? (1 point)gdb debugger, stop and query program to verify series of hypotheses for finding bugs.

École Polytechnique de Montréal Page 7 de 20 Département de génie informatique et génie logiciel

Page 9: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

FIGURE 3 – Outil #2 (http ://www.drdobbs.com/go-parallel/article/print ?articleId=227100038).

b) Quel est le nom et le but de l’outil #2 dans la Figure 3 ? Que pouvez-vous observer dansla Figure concernant le système analysé ? (1 point) gprof profiler, top methods take lon-gest time, although not called that often.

FIGURE 4 – Outil #3 (http ://wiki.crc.nd.edu/wiki/index.php/Main_Page).

c) Quel est le nom et le but de l’outil #3 dans la Figure 4 ? Que pouvez-vous observer dansla Figure concernant le système analysé ? (1 point) valgrind memory checker, there isleak in main function.

École Polytechnique de Montréal Page 8 de 20 Département de génie informatique et génie logiciel

Page 10: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

5 Programmation défensive (6 points)a) Considérez le code fourni en annexe B du jeu vidéo Jedi Outcast. Expliquez ce que les

développeurs ont fait pour faciliter la programmation défensive. En particulier, donnezle but de (1) la classe en ligne 4, (2) les méthodes en lignes 9, 26 et 57 et (3) les ma-cros en lignes 63 et 70. (2 points) Central error reporting class, which generates reportin destructor, allows to signal an error with an error message and line number, and isaccessed through singleton instance obtained through method on line 57. In debuggingmode, the reporter class is used through the three macros, so developers do not need toknow about the class itself, just the macros. In production mode, the empty macros areused instead (no need to remove macros in code).

b) Qu’est-ce qui se passera pendant l’exécution de la fonction main en ligne 78 ? Est-ceque le programme est actuellement exécuté par un développeur (pendant le développe-ment) ou par un utilisateur (produit final) ? Dans le premier cas, comment pourrait-onconfigurer le programme pour un utilisateur ? Dans le deuxième cas, comment pourrait-on configurer le programme pour un développeur ? (2 points) Debugging mode, so anerror is logged and will pop up in report. Go to production mode by undefining line 77.

c) Discutez les lignes 27 et 47. Additionnellement, répondez aux deux questions suivantes :Pourquoi a-t-on choisi une telle approche ? Donnez aussi une approche alternative. (2points) Video game, so development-time assert is OK (especially since only duringdebugging the error reported is used). Maybe use generic error message if no messageprovided.

6 Restructuration du code (6 points)Pour chacun des 6 exemples de code :

— Indiquez en une ligne quel est le problème principal (qui vous apparaît le plus évident),s’il y en a un.

— S’il y a un problème, décrivez brièvement la restructuration qui serait pertinent d’appli-quer afin d’améliorer le code. Pour vous aider, rapportez-vous aux opérations vues encours. N’indiquez pas le code restructuré.

— S’il n’y a pas de problème, expliquez pourquoi.

a) Exemple 1 (C++) :1 //adapté de Audacity 2.0.5, fichier src/ImageManipulation.cpp2 wxImage *OverlayImage(wxImage * background, wxImage * foreground,3 wxImage * mask, int xoff, int yoff)4 {5 unsigned char *bg = background->GetData();6 unsigned char *fg = foreground->GetData();7 unsigned char *mk = mask->GetData();8

9 int bgWidth = background->GetWidth();10 int fgWidth = foreground->GetWidth();11 int mkWidth = mask->GetWidth();12

École Polytechnique de Montréal Page 9 de 20 Département de génie informatique et génie logiciel

Page 11: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

13 int bgHeight = background->GetHeight();14 int fgHeight = foreground->GetHeight();15 int mkHeight = mask->GetHeight();16

17 //Make sure the foreground size is no bigger than the mask18 int wCutoff = (fgWidth < mkWidth) ? fgWidth : mkWidth;19 int hCutoff = (fgHeight < mkHeight) ? fgHeight : mkHeight;20

21

22 // If the masked foreground + offset is bigger than the background, masking23 // should only occur within these bounds of the foreground image24 wCutoff = (bgWidth - xoff > wCutoff) ? wCutoff : bgWidth - xoff;25 hCutoff = (bgHeight - yoff > hCutoff) ? hCutoff : bgHeight - yoff;26

27

28 //Make a new image the size of the background29 wxImage * dstImage = new wxImage(bgWidth, bgHeight);30 unsigned char *dst = dstImage->GetData();31 memcpy(dst, bg, bgWidth * bgHeight * 3);32 return dstImage;33 }

variable spans too largereorder lines to group variables

b) Exemple 2 (Java) :1 //adapté de https://www.simple-talk.com/dotnet/.net-framework/exploring-smelly-code/2 public class Address{3 private String addressLine;4 private String city;5 private String state;6 private String postalCode;7

8 ...9

10 public String getAddressLine{11 return addressLine;12 }13 public String getCity{14 return city;15 }16 public String getState{17 return state;18 }19 public String getPostalCode{20 return postalCode;21 }22 }23

24 public class Order{25 private Address currentAddress = null;26

27 ...28

29 public String MailingAddress(){30 StringBuilder sb = new StringBuilder ();31 sb.Append(currentAddress.getAddressLine1());32 sb.Append("\n");

École Polytechnique de Montréal Page 10 de 20 Département de génie informatique et génie logiciel

Page 12: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

33 sb.Append(currentAddress.getCity() + ", " + currentAddress.getState());34 sb.Append("\n");35 sb.Append(currentAddress.getPostalCode());36 return sb.ToString();37 }38 }

feature envymove function/responsability to Address

École Polytechnique de Montréal Page 11 de 20 Département de génie informatique et génie logiciel

Page 13: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

c) Exemple 3 (C++) :1 //adapté de Audacity 2.0.5, fichier src/LabelDialog.cpp2 void LabelDialog::OnCellChange(wxGridEvent &event)3 {4 static bool guard = false;5 int row = event.GetRow();6 RowData *rd;7

8 if (guard) {9 return;

10 }11 guard = true;12

13 // The change was to an existing label, so go process it based14 // on which column was changed.15 rd = mData[row];16 switch (event.GetCol())17 {18 case Col_Track:19 OnChangeTrack(event, row, rd);20 break;21

22 case Col_Label:23 OnChangeLabel(event, row, rd);24 break;25

26 case Col_Stime:27 OnChangeStime(event, row, rd);28 break;29

30 case Col_Etime:31 OnChangeEtime(event, row, rd);32 break;33 }34

35 // Done...no need for protection anymore36 guard = false;37

38 return;39 }

no problemevent handlers !

École Polytechnique de Montréal Page 12 de 20 Département de génie informatique et génie logiciel

Page 14: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

d) Exemple 4 (C++) :1 //adapté de Audacity 2.0.5, fichier src/LabelDialog.cpp2 void LabelDialog::OnChangeStime(wxGridEvent & WXUNUSED(event), int row, RowData *rd)3 {4 // Remember the value...no need to repopulate5 mGrid->GetCellValue(row, Col_Stime).ToDouble(&rd->stime);6 if (rd->etime < rd->stime) {7 rd->etime = rd->stime;8 mGrid->SetCellValue(row, Col_Etime, wxString::Format(wxT("%g"), rd->etime));9 }

10

11 return;12 }13

14 void LabelDialog::OnChangeEtime(wxGridEvent & WXUNUSED(event), int row, RowData *rd)15 {16 // Remember the value...no need to repopulate17 mGrid->GetCellValue(row, Col_Etime).ToDouble(&rd->etime);18 if (rd->etime < rd->stime) {19 rd->stime = rd->etime;20 mGrid->SetCellValue(row, Col_Stime, wxString::Format(wxT("%g"), rd->stime));21 }22

23 return;24 }25

26 void LabelDialog::OnOK(wxCommandEvent & WXUNUSED(event))27 {28 if (mGrid->IsCellEditControlShown()) {29 mGrid->SaveEditControlValue();30 mGrid->HideCellEditControl();31 return;32 }33

34 // Standard handling35 if (Validate() && TransferDataFromWindow()) {36 EndModal(wxID_OK);37 }38

39 return;40 }41

42 void LabelDialog::OnCancel(wxCommandEvent & WXUNUSED(event))43 {44 if (mGrid->IsCellEditControlShown()) {45 mGrid->GetCellEditor(mGrid->GetGridCursorRow(),46 mGrid->GetGridCursorCol())47 ->Reset();48 mGrid->HideCellEditControl();49 return;50 }51

52 // Standard handling53 EndModal(wxID_CANCEL);54

55 return;56 }

duplication/cloningextract common things into one function

École Polytechnique de Montréal Page 13 de 20 Département de génie informatique et génie logiciel

Page 15: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

e) Exemple 5 (C++) :1 //adapté de Audacity 2.0.5, fichier src/MixerBoard.h2 class MixerBoard : public wxWindow3 {4 friend class MixerBoardFrame;5

6 public:7 MixerBoard(AudacityProject* pProject,8 wxFrame* parent,9 const wxPoint& pos = wxDefaultPosition,

10 const wxSize& size = wxDefaultSize);11 virtual ~MixerBoard();12

13 // Add clusters for any tracks we’re not yet showing.14 // Update pointers for tracks we’re aleady showing.15 void UpdateTrackClusters();16

17 int GetTrackClustersWidth();18 void MoveTrackCluster(const Track* pTrack, bool bUp); // Up in TrackPanel is left in MixerBoard.19 void RemoveTrackCluster(const Track* pTrack);20

21 wxBitmap* GetMusicalInstrumentBitmap(const wxString name);22

23 bool HasSolo();24

25 void RefreshTrackCluster(const Track* pTrack, bool bEraseBackground = true);26 void RefreshTrackClusters(bool bEraseBackground = true);27 void ResizeTrackClusters();28

29 void ResetMeters(const bool bResetClipping);30

31 void UpdateName(const Track* pTrack);32 void UpdateMute(const Track* pTrack = NULL); // NULL means update for all tracks.33 void UpdateSolo(const Track* pTrack = NULL); // NULL means update for all tracks.34 void UpdatePan(const Track* pTrack);35 void UpdateGain(const Track* pTrack);36

37 void UpdateMeters(const double t1, const bool bLoopedPlay);38

39 void UpdateWidth();40

41 private:42 void CreateMuteSoloImages();43 int FindMixerTrackCluster(const Track* pTrack,44 MixerTrackCluster** hMixerTrackCluster) const;45 void LoadMusicalInstruments();46

47 // event handlers48 void OnSize(wxSizeEvent &evt);49

50 ...51 };

low cohesionsplit class

École Polytechnique de Montréal Page 14 de 20 Département de génie informatique et génie logiciel

Page 16: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

f) Exemple 6 (C++) :1 class MixerTrackCluster : public wxPanel2 {3 public:4 MixerTrackCluster(wxWindow* parent,5 MixerBoard* grandParent, AudacityProject* project,6 WaveTrack* pLeftTrack, WaveTrack* pRightTrack = NULL,7 const wxPoint& pos = wxDefaultPosition,8 const wxSize& size = wxDefaultSize);9 virtual ~MixerTrackCluster() {};

10

11 void HandleResize(); // For wxSizeEvents, update gain slider and meter.12

13 void HandleSliderGain(const bool bWantPushState = false);14 void HandleSliderPan(const bool bWantPushState = false);15

16 void ResetMeter(const bool bResetClipping);17

18 ...19

20 public:21 // mTrack is redundant, but simplifies code that operates on either22 // mLeftTrack or mNoteTrack.23 Track* mTrack; // either mLeftTrack or mNoteTrack, whichever is not NULL24

25 WaveTrack* mLeftTrack; // NULL if Note Track26 WaveTrack* mRightTrack; // NULL if mono27

28 //vvv Vaughan, 2010-11-05:29 NoteTrack* mNoteTrack; // NULL if Wave Track30

31

32 private:33 MixerBoard* mMixerBoard;34 AudacityProject* mProject;35

36 // controls37 wxStaticText* mStaticText_TrackName;38 wxBitmapButton* mBitmapButton_MusicalInstrument;39 AButton* mToggleButton_Mute;40 AButton* mToggleButton_Solo;41 MixerTrackSlider* mSlider_Pan;42 MixerTrackSlider* mSlider_Gain;43 Meter* mMeter;44

45 public:46 DECLARE_EVENT_TABLE()47 };

public attributesmake private

École Polytechnique de Montréal Page 15 de 20 Département de génie informatique et génie logiciel

Page 17: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

7 Tests du développeur (9 points)Pour la question qui suit, considérez à nouveau le code fourni en annexe A.

a) Tracez le graphe de flot de contrôle de la fonction Jedi_ClearPathToSpot. Ne recopiezpas le code au complet dans les noeuds, n’utilisez que le ou les numéros de lignes cor-respondantes, sauf où une ligne appartient à plusieurs nœuds (exemple : (1), (7,8,9),(a<45), etc.). (3 points) Version avec “continue” nodes also accepted, as well as versionwhere “i++” or “continue” nodes are shared :

2-11

12a

53-54

17

19a

19b

21 23

27-32

40-45

51

end

14 12b

33-34 36-37

39

46a

46b

46c

48

b) Quelle est la complexité cyclomatique de la fonction Jedi_ClearPathToSpot et que si-gnifie cette valeur dans le contexte de tests de couverture de code ? (2 points)E=30, N=21, alors complexité cyclomatique : 30-21+2=11. Cela représente le nombremaximal de cas de tests nécessaires pour obtenir une couverture complète du code.

c) Donnez un ensemble minimal de tests nécessaires pour couvrir la fonction Jedi_ClearPathToSpot

École Polytechnique de Montréal Page 16 de 20 Département de génie informatique et génie logiciel

Page 18: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

entièrement (chaque ligne), c.-à-d. :

(a) Donnez le nombre minimal de différents jeux de paramètres avec lesquels il fautexécuter la fonction. (0.5 point)

(b) Donnez pour chaque jeu de paramètres les valeurs et (si nécessaire) les caractéris-tiques particulières des paramètres. Par exemple, pour un paramètre qui représenteun tableau de deux éléments avec des caractéristiques particulières, vous pourriezrépondre [“impactEntNum>0”,“dest.isEmpty()”] pour un cas de test spécifique. (1.5point)

7 : from 39 to 51 we only need 1 instead of 4, by picking for [trace.fraction < 1.0f ||trace.allsolid || trace.startsolid] the following ones in the NPC array : (T,F,F), (F,T,F),(F,F,T) and (F,F,F)

d) Qu’est-ce qu’un test du flux de données ? Est-ce qu’il faut ajouter des tests du flux dedonnées pour la variable drop, ou est-ce que les tests de flot de contrôle sont suffisants ?Dans le premier cas, indiquez les nouveaux tests sur le graphe de flot de contrôle. (2points) if we had 27-32 => 33-34 => 39 => 53-54 and 27-32 => 36-37 => 39 => 40-45=> rest of loop before, we now need to add 27-32 => 33-34 => 39 => 40-45 => 39 =>43-54 as well to cover all definition - use of drop

Nous vous souhaitons beaucoup de succès dans le restant de vos études et de votre cheminementde carrière !

Bram et Fehmi

École Polytechnique de Montréal Page 17 de 20 Département de génie informatique et génie logiciel

Page 19: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

Annexe A1 static qboolean Jedi_ClearPathToSpot( vec3_t dest, int impactEntNum ){2 trace_t trace;3 vec3_t mins, start, end, dir;4 float dist, drop;5

6 //Offset the step height7 VectorSet( mins, NPC->mins[0], NPC->mins[1], NPC->mins[2] + STEPSIZE );8

9 gi.trace( &trace, NPC->currentOrigin, mins, NPC->maxs, dest, NPC->s.number, NPC->clipmask );10

11 //Do a simple check12 if ( trace.allsolid || trace.startsolid ){13 //inside solid14 return qfalse;15 }16

17 if ( trace.fraction < 1.0f ){18 //hit something19 if ( impactEntNum != ENTITYNUM_NONE && trace.entityNum == impactEntNum ){20 //hit what we’re going after21 return qtrue;22 }else{23 return qfalse;24 }25 }26

27 //otherwise, clear path in a straight line.28 //Now at intervals of my size, go along the trace and trace down STEPSIZE to make sure29 //there is a solid floor.30 VectorSubtract( dest, NPC->currentOrigin, dir );31 dist = VectorNormalize( dir );32 if ( dest[2] > NPC->currentOrigin[2] ){33 //going up, check for steps34 drop = STEPSIZE;35 }else{36 //going down or level, check for moderate drops37 drop = 64;38 }39 for ( float i = NPC->maxs[0]*2; i < dist; i += NPC->maxs[0]*2 ){40 //FIXME: does this check the last spot, too? We’re assuming that should be okay41 //since the enemy is there?42 VectorMA( NPC->currentOrigin, i, dir, start );43 VectorCopy( start, end );44 end[2] -= drop;45 gi.trace( &trace, start, mins, NPC->maxs, end, NPC->s.number, NPC->clipmask );//NPC->mins?46 if ( trace.fraction < 1.0f || trace.allsolid || trace.startsolid ){47 //good to go, check next one48 continue;49 }50 //no floor here! (or a long drop?)51 return qfalse;52 }53 //we made it!54 return qtrue;55 }

(adapté de : git://git.code.sf.net/p/jedioutcast/code, fichier code/game/AI_Jedi.cpp)

École Polytechnique de Montréal Page 18 de 20 Département de génie informatique et génie logiciel

Page 20: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

Annexe B1 #if G2API_DEBUG2

3 #define MAX_ERROR_PRINTS (3)4 class ErrorReporter{5 string mName;6 map<string,int> mErrors;7 public:8 ErrorReporter(const string &name): mName(name) {}9 ~ErrorReporter(){

10 int total=0;11 cerr << "****** " << mess <<" Error Report Begin******\n";12

13 map<string,int>::iterator i;14 for (i=mErrors.begin();i!=mErrors.end();i++)15 {16 total+=(*i).second;17 cerr << (*i).first.c_str() << " (hits " << (*i).second << ")\n";18 }19

20 cerr << "****** " << mName.c_str()21 << " Error Report End " << total22 << " errors of " << mErrors.size()23 << " kinds******\n";24 }25

26 int Error(const char *m,int kind,const char *, int line){27 assert(m);28 string full=mName;29 if (kind==2){30 full+=":NOTE: ";31 }else if (kind==1){32 full+=":WARNING: ";33 }else{34 full+=":ERROR : ";35 }36 full+=m;37 cerr << " [line " << line << "]";38

39 int ret=0;40 map<string,int>::iterator f=mErrors.find(full);41 if (f==mErrors.end())42 {43 ret++;44 mErrors.insert(pair<string,int>(full,0));45 f=mErrors.find(full);46 }47 assert(f!=mErrors.end());48 (*f).second++;49 if ((*f).second<=MAX_ERROR_PRINTS&&kind<2){50 cerr << full.c_str() << " (hit # " << (*f).second << ")\n";51 }52 return ret;53 }54 };55

56 #include "assert.h"57 ErrorReporter &G2APIError()58 {59 static ErrorReporter singleton("G2API");60 return singleton;61 }62

63 #define G2ERROR(exp,m) (void)( (exp) || (G2APIError().Error(m,0,__FILE__,__LINE__), 0) )

École Polytechnique de Montréal Page 19 de 20 Département de génie informatique et génie logiciel

Page 21: LOG1000 - Ingénierie logicielle Automne 2013 Examen final · complexité du logiciel.V 1.9 En programmation en binôme, il vaut mieux que les différents dévelop-peurs soient jumelés

LOG1000 – Examen final – Automne 2013

64 #define G2WARNING(exp,m) (void)( (exp) || (G2APIError().Error(m,1,__FILE__,__LINE__), 0) )65 #define G2NOTE(exp,m) (void)( (exp) || (G2APIError().Error(m,2,__FILE__,__LINE__), 0) )66 #define G2ANIM(ghlInfo,m) (void)((G2APIError().AnimTest(ghlInfo,m,__FILE__,__LINE__), 0) )67

68 #else69

70 #define G2ERROR(exp,m) ((void)0)71 #define G2WARNING(exp,m) ((void)0)72 #define G2NOTE(exp,m) ((void)0)73 #define G2ANIM(ghlInfo,m) ((void)0)74

75 #endif76

77 #define G2API_DEBUG78 int main(void){79 int nr_joueurs=-1;80

81 G2ERROR(nr_joueurs>0,"players");82 }

(adapté de : git://git.code.sf.net/p/jedioutcast/code, fichier code/ghoul2/g2_api.cpp)

École Polytechnique de Montréal Page 20 de 20 Département de génie informatique et génie logiciel