Skip to content

Commit 870254e

Browse files
committed
Create Chapter 7
1 parent ddd7e7a commit 870254e

6 files changed

Lines changed: 255 additions & 8 deletions

File tree

src/appendices/attachments.tex

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
\chapter*{Mellékletek}
2-
\vspace{2 cm}
32

43
\begin{figure}[ht]
54
\hspace*{-1cm}
65
\centering
7-
\begin{minted}{BNF}
6+
\begin{minted}[fontsize=\scriptsize]{BNF}
87
<constraint> ::= <suite> "&" <build-option-constraints>
98

109
<build-option-constraints> ::= <build-option-constraints> "&" <build-option>
@@ -23,7 +22,7 @@ \chapter*{Mellékletek}
2322

2423
\begin{figure}[ht]
2524
\centering
26-
\begin{minted}{python}
25+
\begin{minted}[fontsize=\scriptsize]{python}
2726
class ConfigManager:
2827
def __init__(self, config_file: "StrOrPath", section: str = "DEFAULT") -> None: ...
2928
def get_item(self, item: str, default: str | None = None) -> str: ...
@@ -42,6 +41,34 @@ \chapter*{Mellékletek}
4241
\caption{\label{fig:config-manager} A \textit{ConfigManager} publikus interfésze}
4342
\end{figure}
4443

44+
\begin{figure}[ht]
45+
\centering
46+
\begin{minted}{INI}
47+
[DEFAULT]
48+
COMPILE_TIMEOUT = 5
49+
RUN_TIMEOUT = 5
50+
PREFIX = test_
51+
HOST_COMPILERS =
52+
HOST_GCC
53+
HOST_CLANG_15
54+
55+
[CSMITH]
56+
TIMEOUT = 5
57+
OPTIONS = --no-argc --max-array-dim 5 --max-array-len-per-dim 20 --no-longlong --no-packed-struct --max-block-size 1
58+
59+
[HOST_GCC]
60+
COMPILER = gcc
61+
COMPILE_FLAGS = -std=c99 -Wno-narrowing -Wno-unused-value -fstrict-aliasing -Wformat
62+
LINK_FLAGS =
63+
64+
[HOST_CLANG_15]
65+
COMPILER = clang-15
66+
COMPILE_FLAGS = -std=c99 -Wno-narrowing -Wno-unused-value -fstrict-aliasing -Wformat
67+
LINK_FLAGS =
68+
\end{minted}
69+
\caption{\label{fig:gekko-config} Egy példa \textit{Gekko} konfigurációs fájl}
70+
\end{figure}
71+
4572
\begin{figure}[ht]
4673
\centering
4774
\begin{minted}{INI}

src/chapters/chapter-2.tex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ \chapter{Szoftver architektútra}
99

1010
\section{A projekt felépítés}
1111

12-
Ebben a fejezetben röviden ismertetem a szoftverkomponenseket amelyek felépítik a \textit{SuperSet} elosztott teszt
13-
keretrendszert alkamazást. Mélyebb működésükre, konkrét implementációs részleteikre, és az azokat alátámasztó
12+
Ebben a fejezetben röviden ismertetem a szoftver komponenseket amelyek felépítik a \textit{SuperSet} elosztott
13+
teszt keretrendszert alkamazást. Mélyebb működésükre, konkrét implementációs részleteikre, és az azokat alátámasztó
1414
indoklásokora a komponensek saját fejezeteiben fogok kitérni.
1515

1616
A teszt keretrendszer hét fő szoftver komponensből áll amelyek két \emph{nem} diszjunkt halmazba sorolhatók.
@@ -105,7 +105,7 @@ \section{A projekt felépítés}
105105
standard \textit{JUnit XML} formátumot használja. Ez utóbbi formátum más alkalmazások által is felismerhető így
106106
lehető teszi az eredmények vizualizálását harmadik féltől származó szoftverekben is.
107107

108-
\section{Összegzés}
108+
\section{Összegzés}\label{sec:ch2-summary}
109109

110110
Most, hogy megismerkedtünk röviden a teszt keretrendszert felépítő szoftver komopnensekkel, a következő
111111
fejezetekben kitérek a mélyebb implementációs részletekre. A komponenseket az alkalmazáson átfolyó adatiránynak

src/chapters/chapter-6.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
\chapter{A \textit{Reporter} komponens}
1+
\chapter{A \textit{Reporter} komponens}\label{chp:reporter}
22

33
A \textit{Reporter} szoftver komponens felelős a teszt keretrendszer kimenetét különböző formátumokra hozni.
44
Kiemelendő, hogy ez a komponens egy külön parancsosori futtatható a teszt keretrendszertől. Ezt az architektúrális

src/chapters/chapter-7.tex

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
\chapter{A \textit{Gekko} szoftver komponens}
2+
3+
Bár a~\ref{sec:ch2-summary} fejezetben azt ígértem, hogy az adatiránynak megfelelő sorrendben mutatom be szoftver
4+
komponenseket, a \textit{Gekko} komponenes pedig egy opcionális nulladik lépés, ennek ellenére az utolsó komponens
5+
fejezetben ismertetem.
6+
7+
Ennek legfőbb okai, hogy a \textit{Gekko} komponenes használata opcionális, és a~\ref{chp:reporter} fejezetben
8+
megismert szoftverkomponenshez hasonlóan egy külön parancsosori futtatható.
9+
10+
A \textit{Gekko} komponenes célja, hogy egy megfelelő teszt generátor alkalmazást felhasználva, létrehozni egy olyan
11+
testcsomagot amely kompatibilis a teszt keretrendszerrel. Gyakorlatilag egy \textit{frontendet} biztosít különböző
12+
teszt generátorokhoz, melyek közül tartalmaz egy implementációt a \textit{Csmith}~\cite{csmith} teszt generátorhoz.
13+
14+
Az eredeti ötlet egy egyszerű szkript megvalósítása volt, amely generál valamennyi tesztesetet
15+
\textit{Csmith-el}~\cite{csmith}, majd kimenetüket átkonvertálja a teszt keretrendszer által ismertre. Ennél azonban
16+
generikusabb és robosztusabb megoldást választottam.
17+
18+
A generátor alkalmazás által létrehozott teszteseteket megvizsgálja egy vagy több ismert stabil fordítóprogrammal, hogy
19+
keletkezzen egy viszonyítási alap. Erre azért van szükség mert előfordulhat, hogy egy generált teszteset bizonyos
20+
fordítóprogramon lefordul másikon pedig nem. Az ilyen tesztek nem várt bukásokat eredményezhetnek a tesztelés alatt
21+
álló fordítóprogramot használva. Az ilyen típusú hibákat nehéz megtalálni így jobb elkerülni.
22+
23+
A \textit{Gekko} komponens szoftver architektúrális szempontból fel van készítve arra, hogy egyéb teszt generátorokat
24+
is meg tudjon hajtani, a jelen implementáción túl. Ezt többek között a \textit{Python} által nyújtott \textit{Protocol}
25+
osztályokkal valósítottam meg, amik lehetővé teszik a \textit{Struktúrált típusosság} alkalmazását a \textit{Pythonban}
26+
megszokott \textit{Duck típusosság} helyett. Ennek használatával inheritencia nélkül, implicit módon lehet
27+
implementálni interfészeket, a típus korrektség megőrzése mellett.
28+
29+
\newpage
30+
31+
\section{A komponenes konfigurácjója}
32+
33+
A \textit{Gekko} szoftver komponenes újrahasználja a~\ref{chp:config-manager} fejeyetben megismert
34+
\textit{ConfigManager} komponenst, és definiálja a saját konfigurációs fájl formátumát.
35+
36+
A konfigurációs fájl az alábbi szekciókat támogatja:
37+
38+
\begin{itemize}
39+
\item \textit{DEFAULT}: itt adahatóak meg \textit{Gekko} konfigurációi. A \verb|COMPILE_TIMEOUT| és a
40+
\verb|RUN_TIMEOUT| amik a verifikáló fordítóprogramok futás idejét, illetve a generált tesztek
41+
futásidejét korlátozzák. A \verb|PREFIX| kapcsolóval a generált tesztesetek nevének előtagja
42+
változtatható. A \verb|HOST_COMPILERS| pedig egy lista azokból a fordítóprogramokból amik a viszonyítási
43+
alapot fogják adni.
44+
\item \textit{CSMITH}: A jelenleg támogatott generátor kapcsolói. Itt adható meg az \verb|OPTIONS| kapcsolóval
45+
a program parancssori argumentumai. A \verb|TIMEOUT| kapcsolóval megszorítható a generátor futásideje egy
46+
időkeretbe.
47+
\item A további szekciókban a verfikáló fordítóprogramokat lehet felsorolni a \textit{DEFAULT} szekció
48+
\verb|HOST_COMPILERS| kapcsolója számára. Ezen szekciók kapcsolói, a \verb|COMPILER| ami a program
49+
elérési útvonala, a \verb|COMPILE_FLAGS| ami a fordítási kapcsolók megadására szolgál, és a
50+
\verb|LINK_FLAGS| ahol a szerkesztő program számára lehet kapcsolókat átadni.
51+
\end{itemize}
52+
53+
A \textbf{\ref{fig:gekko-config}. ábrán} látható egy példa a konfigurációs fájlra.
54+
55+
\section{A komponens felépítése}
56+
57+
A \textit{workers} parancssori argumentummal finomhangolható, az egyidejűleg generált tesztesetek száma. Ez a
58+
kapcsoló szemantikailag nem összekeverndő, az összesen generálni kívánt tesztesetek számát szabályzó
59+
\textit{num-tests} kapcsolóval.
60+
61+
A komponens a teszt keretrendszerhez hasonlóan egy aszinkron esemény hurokban fut. Az esemény hurkon egyszerre
62+
maximum a \textit{workers} kapcsoló által megadott mennyiségű egyidejű feladat fut. Ezt egy \textit{Szemafor}
63+
szabályozza amely csak a \textit{workers} parancssori argumentumnak megfelelő feladatot enged egyidejűleg futtatni.
64+
A \textit{Gekko} komponenes viszont egyszerre dupla annyi feladatot tesz fel az esemény hurokra mint amennyi
65+
egyidejűleg futhat.
66+
67+
Erre azért van szükség, mert annyi teszteset generálásért felelős feladat jön létre, \\ amennyi a
68+
\textit{num-tests} értéke. Tehát a feladatok száma lineárisan nő, a generálandó tesztesetek számával. A korlátozás
69+
azért van, hogy a feladatok számából következő lineárisan növekvő tráigény, felülről korlátos legyen. Továbbá, ha
70+
gyorsabban regisztrálódnak feladatok az esemény hurkon mint ahogyan elfogynak, akkor a \textit{Szemaforért} is
71+
zárolási verseny alakulna ki, ezt az esetet is kizárja a felsőkorlát beiktatása.
72+
73+
A \textit{Gekko} által futtatott aszinkron feladatok három alkomponensből állnak össze. Ezen komponensek
74+
\textit{UML Komponens diagramját} ábrázolja a \textbf{\ref{fig:gekko-uml}. ábra}.
75+
76+
\begin{figure}[ht]
77+
\centering
78+
\hrule
79+
\begin{tikzpicture}
80+
\begin{umlcomponent}{Gekko}
81+
\umlbasiccomponent[y=3.3]{Transformer}
82+
\umlbasiccomponent[x=2]{EvaluationEngine}
83+
\umlbasiccomponent[x=4,y=3.3]{TestGenerator}
84+
85+
\umlport{TestGenerator}{0}
86+
\umlrequiredinterface[interface=Config, with port]{TestGenerator}
87+
\umlprovidedinterface[interface=SSCTest, with port]{Transformer}
88+
89+
\umlHVassemblyconnector[interface=TestCase, with port, anchor1=0, anchor2=-60, second arm]{EvaluationEngine}{TestGenerator}
90+
\umlVHassemblyconnector[interface=GoodTest, with port, anchor1=-120, anchor2=180, first arm]{Transformer}{EvaluationEngine}
91+
\end{umlcomponent}
92+
93+
\umlHVHrelation{Gekko-east-port}{TestGenerator-east-interface}
94+
\umlHVHrelation{Transformer-west-interface}{Gekko-west-port}
95+
96+
\umlport{Gekko}{0}
97+
\umlport{Gekko}{180}
98+
\end{tikzpicture}
99+
\hrule
100+
\caption{\label{fig:gekko-uml} \textit{Gekko UML Komponens} diagram}
101+
\end{figure}
102+
103+
\newpage
104+
105+
Az architektúra gyakorlatilag egy csővezeték felépítést követ. Fontos kiemelni, hogy ha a csővezetékben bárhol hiba
106+
keletkezik akkor a rendszer megpróbálja a folyamatot a csővezeték elejéről. Ezt maximum hatszor teszi meg, ha ennyi
107+
alkalommal nem sikerül tesztet generálni, akkor feltételezhetjük hogy egyéb, az alkalmazás működésén kívül eső
108+
probléma áll fent. Az újrapróbálkozás felső korlátja azt is jelenti, hogy a kért teszteseteknél előfordulhat, hogy
109+
kevesebbet generál az alkalmazás. A bementi konfiguráció alapján a \textit{Gekko} a következő lépés sorozatot
110+
hajtja végre, alkomponensek szerint:
111+
112+
\begin{enumerate}
113+
\item Teszteset generálás.
114+
\item Teszteset verfikáció, a konfigurációban definiált fordítóprogramokkal.
115+
\item Verfikált teszteset transzformáció, a \textit{SuperSet} teszt keretrendszer formátumára.
116+
\end{enumerate}
117+
118+
A komponensek számára a konfigurációt elérhetővé kell tenni egy globális helyen, ezt a feladatot
119+
\textbf{\ref{fig:gekko-uml}. ábrán} nem szereplő, \textit{Collector} komponens látja el.
120+
121+
A \textit{Collector} komponens az alábbi fontos konfigurációkat teszi elérhetővé a konfigurációs fájlból
122+
beolvasottakon túl:
123+
124+
\begin{itemize}
125+
\item A teszteset generáló objektumot, amelyen keresztül egy közös interfészen keresztül hívhatóak különböző
126+
teszteset generátorok.
127+
\item A verifikáló fordítóprogram objektumokat.
128+
\end{itemize}
129+
130+
A komponens megvizsgálja a verifikáló fordítóprogramokat pár egyszerű invokációval, így megbizonyosdik róla hogy a
131+
parancssori argumentum interfészük a \textit{Gekko} által ismert. A komponens ezen felül több a futás során
132+
szükséges elérési útvonal létrehozásáról is gondoskodik, például a kimeneti mappájéról, és a \textit{log} fájlok
133+
mappájéról.
134+
135+
\section{A \textit{Gekko} alkomponensei}
136+
137+
Ahogyan azt a \textbf{\ref{fig:gekko-uml}. ábrán} láthattuk az első komponens a \textit{TestGenerator}.
138+
139+
A \textit{TestGenerator} alkomponens az egyetlen publikus tagfüggvényén, a \textit{generate} függvényen keresztül
140+
generál egy tesztesetet. Ezt a konfigurációban megadott, teszteset generátor alkamazás alprocesszusban történő
141+
meghívásával teszi.
142+
143+
A második komponenes az \textit{EvaluationEngine}, vagyis a kiértékelő komponens. Ez a komponens végzi a
144+
\textit{TestGenerator} által generált tesztesetek verfikációját. A konfigurációban megadott fordítóprogramokkal
145+
lefordítja a tesztesetet.
146+
147+
Azonban itt nem fejezi be a munkát. A tény, hogy minden alkalmazott fordítoprogram tudott futtatható állományt
148+
generálni, még nem elég ahhoz, hogy meggyőzödjünk a teszteset helyességéről.
149+
150+
A \textit{Csmith}~\cite{csmith} teszteset generáló program kimeneti forrásfájlai futásidejű tesztesetek.
151+
Kimenetükben egy ellenőrzőössszeget adnak vissza. Ennek az összegnek a helyességét kell verifikálni. Ennek
152+
tudatában, az \textit{EvaluationEngine} implementációja az összes tesztet le is futtatja, és az eredményüket
153+
ellenőrzi, hogy az elvárt ellenőrzőösszeget produkálják.
154+
155+
Eltérés esetén a teszteset nem kerül felhasználásra és a csővezeték hibával megáll. Itt a fentebb említett módon
156+
történhet új tesztesettel újra próbálkozás.
157+
158+
A harmadik alkomponens a \textit{Transformer}. Ahogyan azt az \textit{EvaluationEngine} kapcsán említettem a
159+
\textit{Csmith}~\cite{csmith} kimenete egy specifikus formátumban van.
160+
161+
A formátum tartalmaz metainformációkat a generált tesztesetről, és a generáló programról. Ezek nagyon hasznos
162+
információk, mert nem kell a tesztesetet lefordított futtható állományát elmenteni, ha reprodukálni szeretnénk a
163+
bukást. Egyszerűen a metainformációból újra előállítható a teszteset. A \textit{Transformer} a következő
164+
metainformációkat tárolja el:
165+
166+
\begin{itemize}
167+
\item A generáló alkalmazást, verziójával együtt.
168+
\item A generáló alkalmazás parancssori argumentumait.
169+
\item A \textit{Gekko} saját egyedi azonosítóját \textit{(hash)}.
170+
\item A tesztgeneráló által alkalmazott \textit{seed} érték, amely a véletlen generálást reprodukálhatóvá
171+
teszi.
172+
\end{itemize}
173+
174+
A metainformációkat egy \textit{JSON}~\cite{json} fájlban tárolja a komponens. Az alábbi
175+
\textbf{\ref{fig:metadata-json}. ábrán} látható módon.
176+
177+
\newpage
178+
179+
\begin{figure}[ht]
180+
\centering
181+
\begin{minted}{json}
182+
{
183+
"test_1.c": {
184+
"generator": "csmith 2.4.0",
185+
"options": "--no-argc --max-array-dim 5 --no-longlong --no-packed-struct -o test_1.c",
186+
"revision": "0ec6f1b",
187+
"seed": "15774984650604141557"
188+
}
189+
}
190+
\end{minted}
191+
\caption{\label{fig:metadata-json} Egy teszteset metainformációja \textit{JSON} formátumban}
192+
\end{figure}
193+
194+
\subsection{Az alkomponens interfészek}
195+
196+
A különböző alkomponensek egy-egy interfész rétegen keresztül kommunikálnak egymással. Ez az interfész réteg a
197+
\textit{Python} protokollokra építkezik.
198+
199+
Ahogyan azt a fejezet elején is említettem a protokollokkal elérhető a \textit{struktúrált típusosság}
200+
öröklődés beveztése nélkül. Ez nagyban leegyszerűsíti a kódot, ugyanis elhagyhatók a \textit{Pythonban}
201+
megszokott \verb|@abstractmethod| függvény annotációk.
202+
203+
Ezek elkerülése nem csak a kódolvashatóságon javít, hanem a futás időn is. Ez a javaulás elenyésző ugyan de
204+
attól még említésre méltó. A javulás annak köszönhető, hogy az \textit{abstract} annotációkat a
205+
\textit{Python}, mint ahogyan minden más konstrukciót is, futás időben értékeli ki.
206+
207+
Ezzel szemben, a protokollokat a \textit{Python interpreter} futásidőben nem ellenőrzi. Az ellenőrzésükhöz
208+
szükség van egy harmadik féltől származó típus ellenőrző alkalmazásra. Például, \textit{mypy}~\cite{mypy},
209+
\textit{pyright}~\cite{pyright}, \textit{ty}~\cite{ty}.
210+
211+
A protokollok egy szoftverarchitektúrális szempontból, is előnyesek, mert egy tisztább megoldást kínálnak mint
212+
az egyébként \textit{Pythonban} elérhető \textit{abstract} osztályok. Mivel nem osztályok és nincs szükség
213+
öröklődésre, így adattagokat sosem kapnak az implementációk a protokolloktól.
214+
215+
A protokollok hátránya egyedül a lefelé kasztolásnál jön elő, mert csak a \\ \verb|@runtime_checkable|
216+
annotációval ellátott protokollok tesztelhetők futásidőben. Erre a felhasználásra ideálisabb \textit{abstract}
217+
osztályokat alkalmazni.

src/preamble/abstract.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ \chapter*{Tartalmi összefoglaló}
3434

3535
\noindent
3636
\textbf{A megadott feladat megfogalmazása:} A diplomamunka célja egy fordítóprogram teszt keretrendszer fejlesztése,
37-
modern technológiák felhasználásával. A feladat egy olyan komplex rendszer
37+
modern technológiák felhasználásával. A feladat egy olyan \\ komplex rendszer
3838
tervezése és megvalósítása amely képes különböző fordítóprogramok viselkedését tesztelni bementi fájlokkal. Működését
3939
tekintve, képes elosztottan egy kliens-szerver architektúrát alkamzva dolgozni, ahol egy kitüntetett szerver alkalmazás
4040
vezérli a kliens alkalmazások teszt futtatásait.

src/thesis.tex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@
137137
\newpage
138138
\input{chapters/chapter-6.tex}
139139

140+
\newpage
141+
\input{chapters/chapter-7.tex}
142+
140143
\newpage
141144
\input{appendices/bibliography.tex}
142145

0 commit comments

Comments
 (0)