17 november 2014
STAGEVERSLAG
TEST GUIDANCE FOR THE NEDAP TEST AUTOMATION TOOL
Jeroen Vonk
NEDAP University of Twente Comité: Daan van Beek MSc (Nedap) dr.ir. Axel Belinfante (FMT, University of Twente) Gijs Kant MSc (FMT, University of Twente)
Pagina 1
Inhoudsopgave 1 Stage bij Nedap 1.1 AEOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 NTA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 3 3
2 Stage-inhoud Mogelijke oplossingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5 5
3 TestAdvisor 3.1 Statespace . . . . . . . . . . . . Statespace grootte . . . . . . . . 3.2 BDD representatie van het model Variabelen . . . . . . . . . . . . . Transities . . . . . . . . . . . . . Functies . . . . . . . . . . . . . . 3.3 Statische Analyse . . . . . . . . Variabelen . . . . . . . . . . . . . Functies . . . . . . . . . . . . . . Model . . . . . . . . . . . . . . . Opslag gegevens . . . . . . . . . Analyse . . . . . . . . . . . . . . Verkennen van het model . . . . Travelers . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
6 . 6 . 6 . 7 . 7 . 7 . 7 . 8 . 9 . 9 . 9 . 9 . 10 . 10 . 11
4 Conclusie 4.1 Tijdsbesteding . . . . . . . . . . . . . . . . . . . . 4.2 Behaalde resultaten . . . . . . . . . . . . . . . . . 4.3 Aanbevelingen . . . . . . . . . . . . . . . . . . . . Voltooiing van NTA2 . . . . . . . . . . . . . . . . . Gebruik van een bestaande modelchecker . . . . . Test Guidance op basis van eerdere verkenningen
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
14 14 14 15 15 15 15
Pagina 2
Hoofdstuk 1
Stage bij Nedap In het kader van mijn master Computer Science heb ik de afgelopen periode stage gelopen bij Nedap Security. Gedurende een twintigtal weken ben ik bezig geweest met het ontwerpen van een systeem om het automatisch testen van software te versnellen. Het systeem, Nedap Test Automation (NTA), is een in-house test tool ontworpen door Daan van Beek. De lezer van dit verslag wordt geacht een minimale kennis te beschikken betreffende model checken, inhoudende dat de gebruiker bekend is met termen als: (bounded) model checking, model driven tests, use cases, en (Reduced Ordered) Binary Decision Diagrams (BDD’s) 1 .
1.1
AEOS
Het doel van NTA is het "Model Driven" testen van de AEOS-dashboard. AEOS is het integrale beveiligingssysteem van Nedap. AEOS is een volledig softwareplatform dat met behulp van zogeheten controllers een veelvoud aan functies kan vervullen. Dit kan toegangscontrole, al dan niet met RFID, inbraakdetectie, of het beheer van persoonlijke kluisjes zijn. Om personen in het systeem in te voeren of bepaalde rechten toe te kennen, is er een dashboard. Het AEOS-dashboard is een in flash ontwikkelde applicatie. Dit dashboard communiceert vervolgens met de achterliggende back-end van AEOS. Gezien AEOS continu doorontwikkeld wordt, en sommige van deze nieuwe functies ook invloed hebben op het functioneren van het dashboard is het noodzakelijk dat het dashboard getest wordt. Het testen van het dashboard gebeurde voorheen handmatig. Echter, neemt dit handmatige testen veel tijd in beslag. Dit betreft voornamelijk het testen of reeds geïmplementeerde functionaliteiten beïnvloed worden door nieuwe functies, de zogeheten regressie-testen.
1.2
NTA
Om deze regressietesten te vergemakkelijken is er besloten om een automatisch test-systeem te ontwerpen, NTA. NTA kan grafische interfaces bekijken en beïnvloeden. Daarmee kan NTA het gedrag van een gebruiker of handmatig tester emuleren. Om dit te doen heeft NTA een intern model van het te testen systeem. Door gelijktijdig een functie uit te voeren op het model als in de werkelijkheid kan NTA discrepanties tussen het model en de werkelijkheid detecteren. Zodra een fout gevonden is kan dit betekenen dat er of: een fout in het model zit, of dat er een functionaliteit niet meer naar verwachting werkt. Mits je een goed model hebt zal het tweede het geval zijn. Het model is non-deterministisch en bevat cykels. Het beste kan het gezien worden als een opeenvolging van verschillende use-cases, waarbij na de executie van een use-case één of meerdere andere use-cases geselecteerd kunnen worden. Dit scala aan use-cases kunnen door de cykels en het nondeterminisme in het model zeer complexe testen genereren, die een handmatig tester niet zo snel zou uitvoeren. Een voorbeeld van een simpele login is getoond in Figuur 1.2. (Voor een uitgebreidere uitleg van het model verwijs ik naar hoofdstuk 3.3) Tevens bevat NTA de mogelijkheid om variabelen te gebruiken. Hiermee kan er bijvoorbeeld bepaald worden of een use-case uitgevoerd kan worden. Een voorbeeld is het onthouden of de huidige ingelogde gebruiker al dan niet een administrator is. Het zou immers voor te stellen zijn dat bepaalde testen enkel uitgevoerd dienen te worden wanneer er momenteel een administrator is ingelogd. Deze variabelen tezamen met de huidige positie in het model zijn te beschouwen als de huidige staat van het model in NTA.
1 Daan
van Beek, NTA NodeTypes
Pagina 3
Pagina 4
Hoofdstuk 2
Stage-inhoud Doordat de tool het dashboard, of "System Under Test"(SUT), via de grafische interface benaderd is er soms sprake van een pauze in de executie. Zo kan de SUT bijvoorbeeld nog een scherm moeten laden. Daaruit kunnen we twee dingen concluderen: • NTA zal niet altijd de volledige rekenkracht van de computer gebruiken. • Het uitvoeren van tests neemt veel tijd in beslag, dus het is zaak zoveel mogelijk diverse tests binnen een gegeven tijd uit te voeren. Gedurende deze stage is het doel te kijken naar mogelijkheden om de executie van de hoeveelheid nuttige tests door NTA te vergroten. Wanneer het model enkel deterministisch zou zijn, dan zou deze versnelling puur in de executie van de tests gevonden moeten worden. Het versnellen van de tests is niet wenselijk. De testmethode dient namelijk de interactie en invoer van een normale gebruiker te simuleren. Wanneer de tests uitzonderlijk snel zouden worden uitgevoerd dan kan het gedrag van de SUT niet representatief zijn voor normaal gebruik. Omdat de tests echter ook enig non-determinisme bevatten, is daar ruimte om enkele verbeteringen door te voeren. De aanwezigheid van een keuze welke test of pad gekozen dient te worden na de huidige test is aan NTA. Een random keuze garandeert uiteindelijk volledige dekking van het model (coverage), mits er een aanzienlijke hoeveelheid testen worden gedraaid. Wellicht zou er een manier zijn om deze keuzes dusdanig te maken dat er; geen tests worden overgeslagen, maar dat een voldoende verkenning van de tests sneller gegarandeerd zou zijn. Het doel is dus, gegeven een bepaalde testtijd meer diverse testen te kunnen uitvoeren. Door deze verhoogde coverage zou de kans op het detecteren van bugs omhoog gaan. Voor het berekenen van de prioriteit van de uit te voeren tests zou de idle-tijd van NTA gebruikt kunnen worden.
Mogelijke oplossingen Na enig overleg hebben wij besloten dat hiervoor enkele oplossingen waren. Een optie is om de verkende paden, of tests, bij te houden. Hiermee zou een eerder genomen pad een mindere voorkeur kunnen krijgen om te verkennen of bijvoorbeeld volledig uitgesloten kunnen worden. Probleem is echter dat bepaalde paden een noodzaak zijn om te nemen, wanneer iemand de bereikbare paden na dat punt wenst te bereiken. Een andere oplossing is om alle mogelijke toekomstige paden te verkennen. Hierbij zou bij punten met een keuze beide opties verkend worden. Gezien het legio van de beslissingen niet nondeterministisch zijn, zou op deze manier een groot deel van het model verkend kunnen worden middels bounded model checking. Op basis van deze verkenning zou vervolgens een geïnformeerde keuze kunnen worden gemaakt voor het te volgen pad. Deze keuze zou naar alle waarschijnlijkheid een aanzienlijke verbetering zijn ten opzichte van de huidige random-tactiek, bij het kiezen van een vervolgpad vanaf een non-deterministische keuze. De laatste oplossing, met een statische analyse, bied potentieel de meeste snelheidswinst. Tevens lag deze oplossing in het verlengde van de interesses en voorkennis van zowel de stagiair als begeleider.
Pagina 5
Hoofdstuk 3
TestAdvisor Het doel van de stage is gesteld een zogeheten "Test Advisor"te ontwerpen voor NTA. Deze Test Advisor dient op beslissingspunten een statische analyse te doen van het onderliggende model om te bepalen wat de meest geschikte keuze is om de exploratie te vervolgen. Nota bene, bij deze exploratie zullen wij het gedrag van het model nabootsen, om te kunnen bepalen welke nodes bereikbaar zijn. Wij zijn dus in feite een model van het model aan het exploreren. Hierbij kunnen wij mogelijk gedrag van het originele systeem als non-deterministisch beschouwen. Een voorbeeld hiervan is of een tekstveld al dan niet zichtbaar is in een GUI. Derhalve zullen we beide mogelijkheden verkennen. Wel kunnen we de staat van variabelen modelleren. Met deze variabelen kunnen we de uitkomst van zogeheten guards uitrekenen. Daardoor kunnen bepaalde executiepaden bij voorbaat uitgesloten worden aangezien deze door de guards (in combinatie met de huidige staat van de variabelen) niet bereikbaar zullen zijn. Hiermee zal de statespace drastisch verminderd worden.
3.1
Statespace
Het model bevat een groot aantal mogelijke paden. Gezien het gebruikelijk is dat het model cykels bevat, zijn er een oneindig aantal mogelijk paden. Een oneindig grote statespace is uiteraard niet volledig te verkennen. Dit is zowel qua tijd als opslagruimte een onmogelijkheid. Een manier om toch binnen afzienbare tijd tot een geschikt advies tijd te genereren voor NTA is om het model slechts deels te doorzoeken. Deze methode van enkel een deel van het model verkennen is ook bekend als bounded model-checking. Gegeven dat NTA bij een non-deterministisch punt is beland, zal de Test Advisor een bounded model-check doen vanaf dat punt. Alle mogelijke paden zullen verkend worden, de bound kan of een maximale zoekdiepte behelzen, of een maximale tijd die de Test Advisor mag besteden aan het zoeken. Na deze zoektocht zal er een verzameling van bereikbare nodes zijn. Uit deze verzameling kan vervolgens volgens een nader te bepalen metriek een doelnode gekozen worden. Gegeven dit doel kan vervolgens het te nemen pad beredeneerd worden startend op de huidige positie van NTA. De te gebruiken metriek voor het kiezen van een node kan simpel zijn; uit de bereikbare nodes willekeurig een node kiezen, maar er kan ook een complexere methode bedacht worden. Bij een complexe methode zou er bijvoorbeeld rekening gehouden kunnen worden met eerdere verkenningen van NTA (coverage) en de kans op het succesvol bereiken van deze node.
Statespace grootte De huidige representatie van het model in NTA is een honderdtal megabytes groot. Wanneer wij bounded checking zouden willen doen zou dat inhouden dat er twee keuzes zijn. Of wij exploreren 1 pad per keer, na elke exploratie het model terug brengend in de originele staat. Dit zou weinig tot geen extra ruimte kosten, ten slotte hoeven wij enkel na elke verkenning enkel de bereikbare nodes op te slaan. Een sequentiële exploratie zou echter veel tijd kosten. De tweede optie is de verkenning van meerdere paden gelijktijdig plaats te laten vinden. Bij een dergelijke parallelle verkenning zou bij elke (non-deterministische) keuze beide paden verkend moeten worden. Om beide paden te verkennen zou dus het model gedupliceerd moeten worden bij een dergelijke keuze. De grootte van het model in acht nemende is het makkelijk om te zien dat in een dergelijk geval het geheugenlimiet van de computer aanzienlijk sneller bereikt zou worden voordat het model voldoende diep verkend is. Daarom zou in een dergelijk geval de gehele verkenning een vruchteloze operatie zijn. Een geschikte oplossing voor deze statespace explosie is het reduceren van het formaat van het model. Dit kan door enkel de relevante informatie op te slaan in ons kopie. Deze relevante informatie zou enkel de beschrijving van de paden zijn die er in het model aanwezig zijn - en de relevante variabelen. Deze variabelen zijn nodig omdat deze mede bepalen welke paden toegankelijk zijn. Alle Pagina 6
andere functionaliteiten die in het model zitten hoeven wij niet in het model over te nemen. Deze overige functionaliteiten zijn bijvoorbeeld de nodige code en data in het model die nodig zijn om de SUT te besturen. Naast deze reductie kunnen we ook kiezen om de kopie op een alternatieve wijze op te slaan. Het gebruik van Binary Decision Diagrams (BDD’s) is hiervoor zeer geschikt. Een BDD is een boomstructuur (graaf) waar bij elk niveau in de boom een binaire variabele representeert. Bij elk knoop in deze boom is de keuze tussen twee takken, één waarbij de gerepresenteerde variabele waar is, en één tak waarbij de variabele onwaar is. Onderaan deze boom zijn de bladeren met enkel de waarde WAAR of ONWAAR. Elk pad wat eindigt in een WAAR blad is een geldige staat voor de keuze van waardes voor de gerepresenteerde variabele in de BDD. Één enkele BDD kan dus een veelvoud aan geldige staten representeren.
3.2
BDD representatie van het model
Gezien elk decimaal getal ook in het binaire stelsel omgezet kan worden, kunnen wij in de BDD getallen opslaan. Middels het toepassen van zogeheten relaties op de BDD kunnen we dan dit getal aanpassen. Het originele model zou dan versimpeld kunnen worden als een graaf, elke vertex met zijn eigen unieke nummer. De BDD representeert deze huidige vertex in de variabele V{} met V{} ⊆ Vertices. Gezien de aard van de BDD kan een enkele BDD nu een set van momenteel bereikbare vertices beschrijven. Gegeven dat wij bij vertex 3 of 1 starten met verkennen (V{} = 1, 3). Vervolgens passen wij een relatie R toe die de transitie van vertex 3 of 8 naar vertex 4 of 5 beschrijft. Rv : V{3,8} → V{4,5} . Na toepassing op deze relatie zal de BDD als volgt veranderen: R
v V{1,4,5} V{1,3} −−→
Na deze transitie zullen vertex 4 & 5 dus ook bereikbaar zijn.
Variabelen Wij kunnen nu ook de BDD verrijken door alle variabelen uit het model in de BDD te laden. Dit kan op een vergelijkbare manier als de vertex. Gegeven een variabele vi uit het model met de mogelijke waarden wi,j ∈ vi die vi kan aannemen. Nu kunnen wij een variabele Wi ∈ {0..j} maken waarbij Wi (j) de waarde van wi,j vertegenwoordigd. De zo verkregen BDD bevat dus V en W. De BDD zal nu dus elke mogelijke variabele combinatie en vertex positie kunnen opslaan. Hiermee kunnen we met deze BDD dus één of meerdere states van het systeem weergeven.
Transities Zoals eerder aangegeven hebben we reeds een relatie Rv om een transitie van de ene naar de andere vertice aan te geven. Echter deze vertex is niet de volledige beschrijving van een state. Wat er momenteel nog mist bij deze relatie is een tweetal elementen. Beide elementen hebben betrekking op de variabelen (W) die tevens deel uitmaken van de state. Een eerste element is dat de transitie de waarde van een variabele kan veranderen. RW : W → W 0 Een tweede element is het feit dat een transitie alleen toegestaan kan zijn wanneer een variabele een bepaalde waarde heeft. Dit zijn zogeheten ’guards’. Rg : W Tezamen kunnen wij dus een relatie R definiëren die als volgt is samengesteld: R = Rv ∧ RW ∧ Rg Een transitie in de BDD zal dus gecodeerd worden als: R
{V, W} −→ {V 0 , W 0 }
Functies NTA ondersteund ook nog het gebruik van functie-aanroepen. Dit gebeurt middels de JumpAndReturn-node, een voorbeeld van een functie aanroep is te zien in Figuur 3.2. Functies zouden zonder problemen in de bovenstaande structuur geïmplementeerd kunnen worden. Immers, op het moment dat een functie wordt aangeroepen kan de code van de desbetreffende functie worden ingevoegd op Pagina 7
die positie, of ïnlining". Dit zou echter zorgen voor veel extra states. Idealiter zouden we de functionaliteit van functieaanroepen verplaatsen naar de relaties over de BDD. Gezien functies geen variabelen mee krijgen, en tevens geen waarde retourneren is dit relatief simpel. Met een simpele stack in de BDD kunnen wij bij een functieaanroep de locatie van de aanroep opslaan. Op het moment dat de functie beëindigt wordt zal de executie verder gaan vanaf het punt waar de functie is aangeroepen.
Wij definiëren in de BDD een set van variabele Si met i = 0..n en n de maximale diepte waarin de functies genest zullen worden. Deze n zullen we met behulp van een statische analyse kunnen achterhalen. Si zal vervolgens de waarde bevatten van de vertex waar een functie aanroep vanaf is gedaan. Een relatie R met betrekking tot een functie-aanroep zal dus ook een element Rs bevatten. Deze Rs geeft aan hoe de stack gemanipuleerd dient te worden. Gegeven drie vertices: • Vs : De plek waar de functie aangeroepen wordt • Vr : De plek waar na de functie verder gegaan dient te worden • Vf s : Het begin van de functie • Vf r : Het einde van de functie • V∅ : Gebruikt om een leeg element in de stack aan te geven. Bij een functie aanroep zal deze dus in de vorm zijn van: V = Vs ∧ Sd = V∅ → V = Vf s ∧ Sd = Vr ∧ d = d − 1 Hierbij is d de huidige top van de stack Bij het retourneren ziet de relatie er als volgt uit: V = Vf r ∧ Sd = Vr → V = Vr ∧ Sd = V∅ ∧ d = d + 1
3.3
Statische Analyse
Wij hebben hierboven een simpele weergave gegeven hoe wij het model willen representeren in een BDD. Tevens is er beschreven welke informatie uit het model in de BDD gebruikt zal worden. Echter, wij hebben nog niet gekeken hoe de data nodig voor de BDD uit het model wordt geëxtraheerd. De benodigde informatie zal middels een statische analyse uit het model gehaald worden. Pagina 8
Variabelen Voor de variabelen willen wij weten welke waardes alle variabelen kunnen aannemen. Pas als we hiervan een bovengrens hebben bepaald kunnen wij de variabele in de BDD opslaan. Indien wij een variabele vinden die maar één mogelijke waarde kan aannemen, dan is deze variabele als statisch te beschouwen. In plaats van de variabele in de BDD aan te maken kunnen we dan overal de desbetreffende variabele vervangen met zijn waarde.
Functies Voor functies willen we de volgorde van geneste functie-aanroepen bepalen. Zodoende kunnen we het minimale formaat van de stack bepalen voor de BDD. Ook kan op deze manier de relatie voor elke mogelijke functie-aanroep gegenereerd worden.
Model Het originele model bestaat uit een aantal submodellen. Deze submodellen bevatten vervolgens zogenaamde ModelElements (ME’s). Een ModelElement is middels lijnen verbonden aan één of meerdere andere ME’s. Elke ME heeft een specifieke functie in het model 1 . Een ME kan ook een Guard bevatten, dit is een expressie die geëvalueerd wordt tot een booleaanse waarde. Alleen wanneer deze expressie WAAR is zal NTA deze ME verkennen. Als laatste kan een ME een expressie bevatten, deze expressie kan bepalend zijn voor het gedrag van het ModelElement. Het kan bepalen welke lijnen vanuit deze ME gevolgd mogen worden (deterministisch gedrag) of bijvoorbeeld de waarde aanpassen van een variabele.
Opslag gegevens In Figuur 3.3 staat een simpele weergave van het model. Om informatie met betrekking tot het model op te slaan hebben we een aantal klassen ontworpen die informatie bevatten over het model, de ME’s, en de variabelen in het model. Op deze manier kunnen we op een makkelijke manier informatie opslaan in het model, zonder het model heel erg aan te hoeven passen. ModelInfo bevat algemene informatie over het model. Ook wordt hier relevante informatie opgeslagen met betrekking tot de voortgang van de statische analyse. VertexInfo is gekoppeld aan een ModelElement, zijnde een groep die ModelElementen bevat, of een losse node. in VertexInfo wordt onder andere informatie opgeslagen met betrekking tot het type node.
1 Daan
van Beek, NTA NodeTypes
Pagina 9
De laatste hulpklasse VariableInfo, bevat alle mogelijke waarde die een variabele kan aannemen. Naast deze waarde wordt ook opgeslagen welke waardes andere variabelen dienen aan te nemen om deze waarde aan te nemen. Men neme bijvoorbeeld een variabele a en een variabele b, van b is bekend dat deze de waarde 1 of 2 kan aannemen. a komt voor in drie expressies: a = 5, a = b, en a = 3 ∗ b. Van a kan nu vermeld worden dat het de volgende waardes kan aannemen: • a=5 • a = 1 gegeven b = 1 • a = 2 gegeven b = 2 • a = 3 gegeven b = 1 • a = 6 gegeven b = 2 Ook wordt er in VariableInfo opgeslagen of een variabele refereert naar een andere variabele (vergelijkbaar met pointers).
Analyse In plaats van één enkele functie om het gehele model te analyseren is er gekozen dit in stappen te doen. Een probleem bij de analyse is dat NTA ontwikkeld is naar gelang wat nodig was bij het testen. NTA heeft dus geen zeer duidelijke omschrijving van het innerlijk functioneren van de tool. Bij het uitvoeren van expressies kunnen er dus ambiguïteiten optreden. An sich is dit geen probleem, NTA functioneert tenslotte naar behoren. Maar bij het vertalen van het model naar een BDD dient het exacte gedrag van NTA geïmiteerd te worden. Mocht dit niet het geval zijn dan kan het zijn dat de NTA Test Advisor (NTA2 ) bepaalde bestaande paden niet kan bereiken. Of zelfs niet bestaande paden verkend en adviseert. Recycling van functies Om het gedrag van NTA zo exact mogelijk na te bootsen zullen we voor zover mogelijk gebruik maken van de bestaande functies in NTA. Een eerste functie in NTA is de functie die expressies evalueert. Deze functie, calculate(), retourneert een string met daarin de geëvalueerde expressie. De functie wordt recursief aangeroepen op een expressie. Een expressie bestaat vervolgens uit een linker- en rechtergedeelte. Men neme bijvoorbeeld de expressie a = b + 3, dit evalueert tot: = a
+ b 3
Wanneer wij de calculate functie aanroepen, dan zal de waarde van b opgehaald worden. Vervolgens wordt de waarde van 3 opgehaald. Dan wordt de operator + uitgevoerd op b & 3. De variabele a wordt geladen. En vervolgens wordt het resultaat van de som opgeslagen in a. Wij willen echter voor de statische analyse alle mogelijke waardes van een variabele weten. Daarom hebben wij de functie calculate() omgeschreven naar: calculate(boolean calculateStatic=false). Wanneer de boolean calculateStatic ge-enabled is, dan zal calculate alle mogelijke waardes uitrekenen, gegeven de mogelijke waardes van de variabeles. Deze mogelijke waardes voor de variabele zijn opgeslagen in de klasse VariableInfo.
Verkennen van het model Zoals eerder vermeld zullen wij het model in stappen verkennen. Om NTA zelf minimaal aan te hoeven passen hebben we gekozen voor een soort visitor-pattern. Elk ModelElement zal een functie traverseModelElement(func) krijgen die aangeroepen zal worden met een functie visitModelElement() als argument en vervolgens: • visitModelElement() aanroept met het huidige ModelElement als argument • visitModelElement() zal vervolgens de verzamelde data opslaan in het VertexInfo-object gekoppeld aan dit ModelElement • traverseModelElement() aanroept voor alle ModelElementen verbonden met dit ModelElement, hetzij via een normale verbinding, hetzij via een functie-aanroep (jumpAndReturn). Pagina 10
Voor expressies hebben wij eenzelfde patroon gebruikt. Echter, waar de traversal-functie voor ME’s een top-down benadering gebruikt, zullen expressies bottom-up geëvalueerd worden. Er zal dus eerst de traversal-functie aangeroepen worden voor de linker- en rechter-subexpressie. Vervolgens wordt de visitExpression() aangeroepen voor de huidige expressie. Resultaten zullen, indien van toepassing, opgeslagen worden in VariableInfo.
Travelers Het model zal in een paar iteraties verkend worden met verscheidende travelers, de gebruikte travelers worden in de volgorde gebruikt waarin deze hieronder zijn beschreven. Elk van deze ModelElementtravelers zal worden aangeroepen op het initiële ModelElement van het model. Vervolgens zullen deze recursief door het model heen gaan, totdat elk element bezocht is. De Expression-travelers zullen indien nodig worden aangeroepen worden door een ME-traveler op de expressie van het betreffende ModelElement. GraphEdges Deze klasse zorgt ervoor dat alle verbindingen tussen de ME’s opgeslagen worden in VertexInfo. Tevens slaat het op of een klasse een JumpAndReturn is. Indien dat het geval is, dan wordt dit tezamen met de locatie opgeslagen in VertexInfo. GraphReturns Nadat alle verbindingen zijn opgeslagen worden alle JumpAndReturns geanalyseerd. Zodra deze functie een JumpAndReturn tegenkomt zal hij zichzelf recursief aanroepen op de locatie waar de JumpAndReturn heen wijst. De recursie wordt beëindigd zodra de functie een Return tegen komt. Op deze manier kunnen we de maximale diepte van functies achterhalen. Deze diepte wordt opgeslagen - en gebruikt om het formaat van de functie-stack van de BDD te bepalen. Ook worden alle mogelijke functiecalls met hun huidige recursiediepte opgeslagen. Met deze informatie kan uiteindelijk de relatie voor de BDD worden aangemaakt die stack manipuleert. Waarmee de BDD de functiecalls emuleert zonder alle functies te hoeven inlinen. VariableAssignments De VariabeleAssignments-klasse, evalueert of het huidige ModelElement een variabeletoewijzing doet. Dit kan of doordat het ModelElement een zogeheten MultipleOptionsChooser is, of omdat de expressie van de huidige ME een BecomesExpression bevat. Een MultipleOptionsChooser (MOC) heeft als argument (expressie), een variabele en een lijst van waardes. De MOC zal uit de lijst een waarde random kiezen en toekennen aan de variabele. Becomes De ExpressionTraveler Becomes kijkt of een expressie een instantie is van een becomesExpression. Vervolgens wordt de linkerkant van de expressie geëvalueerd om te weten te komen aan welke variabele een waarde toegekend dient te worden. Laten we deze variabele "LHS-var"noemen. De rechterzijde kan of een expressie zijn, of het kan een pointer zijn naar een andere variabele. RetrieveVars Met behulp van de expressionTraveler RetrieveVars wordt gekeken welke variabelen in de rechter subexpressie zitten. Vervolgens wordt in de VariableInfo van LHS-var worden opgeslagen dat LHS-var afhankelijk is van deze variabelen.
Pagina 11
VariableBounds Nu alle afhankelijkheden voor de variabelen zijn uitgeplozen kunnen wij proberen een upperbound te maken voor de waardes die een variabele kan aannemen. Dit wordt gedaan door de "TravExprBoundsklasse
TravExprBounds Het verkennen van de expressie met behulp van de TravExprBounds-klasse kan het best worden uitgelegd met behulp van een stuk psuedo-code. Zie hiervoor de code in Listing 3.1. 1 while ( not VariableBounds . a l l B o u n d ) VariableBounds . a l l B o u n d = t r u e 3 f o r a l l (ME as me) bound = t r u e 5 i f (me. e x p r e s s i o n instanceof BecomesExpression ) f o r a l l (me. e x p r e s s i o n . i n f o ( ) . u s e d V a r i a b l e s as v a r ) 7 i f ( not v a r . isBound ( ) ) bound = f a l s e 9 i f ( bound ) i n f o . addValues (me. e x p r e s s i o n . c a l c u l a t e ( ) ) 11 else VariableBounds . a l l B o u n d = f a l s e
Listing 3.1: Pseudo code voor het verkennen van de bounds van variabelen Alleen wanneer all variabelen waar een LHS-var van af hangt bounded zijn kan de waarde voor deze variabele uitgerekend worden. Dit proces zal dus herhaald worden tot er geen ongebonden variabelen meer zijn.
VariableReferences Wij hebben momenteel voor elke variabele de mogelijke waardes uitgerekend. We missen echter nog een aantal waardes. Er is namelijk nog geen rekening gehouden met het gebruik van pointers. Op het moment dat a bijvoorbeeld naar b wijst, en er een andere waarde aan a wordt toegekend zal deze eigenlijk aan b worden toegekend. VariableReferences zal voor elke LHS-var recursief een functie aanroepen. Deze functie zal alle mogelijke waarden van deze LHS-var toevoegen aan alle variabelen waar LHS-var naar kan refereren. De functie wordt vervolgens weer aangeroepen op de gerefereerde variabelen. Aan het einde hebben we een bovengrens bepaald voor elke variabele, rekening houdende met pointers.
StaticVars Nu we een bovengrens hebben bepaald kunnen we kijken of er variabelen geëlimineerd kunnen worden. Indien de bovengrens bestaat uit precies één waarde dan is de variabele statisch. StaticVars-traveler gaat alle variabelen na, en markeert deze variabelen. Bij het bouwen van de BDD kunnen deze variabelen dan genegeerd worden, en vervangen worden met de waarde van de variabele.
For loops Na alle bovenstaande analyses is er nog een constructie in NTA waar we geen rekening mee hebben gehouden. Te weten de Groups, en specifiek de foreach-group. De foreach zal een loop-variabele voor elke waarde uit een gegeven list initialiseren - en de ModelElements in de foreach-group voor elke waarde van die variabele uitvoeren. Er is voor gekozen om deze loops uit te vouwen (loop unrolling) teneinde ze in de BDD te passen. In een eerste poging is er getracht de uitgevouwde loops in het NTA-model onder te brengen. Dit bleek echter niet mogelijk om alleen lokaal te doen gezien de aard van NTA. NTA wil namelijk elke verandering aan het model doorgeven aan de server, zodat alle andere clients eenzelfde model hebben. Hierna is besloten om zodra de bovengrens van alle variabelen is uitgerekend, er een boolean in ModelInfo wordt aangepast. Deze boolean geeft aan dat bij het verkennen van het model ook in de for-groups gekeken dient te worden. Bij de verkenning zal elke foreach dus geinitialiseerd worden met elke mogelijke waarde uit de lijst. Gezien de forloop ook weer invloed kan hebben op de waardes van variabelen worden bovenstaande ME-travelers allemaal opnieuw uitgevoerd, deze keer rekening houdende met foreach-groups. Mogelijke problemen hierbij is dat alle initialisaties van foreach-executies onderling moeten worden verbonden in de BDD. Verder zal er bij een JumpAndReturn uit een foreach-group een inlining van die code vereist zijn. Verder is het ook toegestaan om foreach-groups in for-each-groups te plaatsen. Dit alles heeft gedurende de stage een aanzienlijke hoeveelheid tijd gekost om te doorgronden en proberen te vangen in code. Pagina 12
BuildBDD De BuildBDD traveler zet de informatie in de Info-klasses om in een BDD. Dit gebeurt door achtereenvolgens de variabelen en stack aan te maken. Vervolgens worden alle relaties toegevoegd. Als laatste wordt de BDD in de begin-state gezet. Gegeven deze BDD en de gegenereerde relaties kan het model verkend gaan worden. DotBuilder De DotBuilder is een klasse die .dot-bestanden kan lezen. Deze bestanden beschrijven een graaf. Het gegenereerde dot-bestand is een grafische weergave van hoe de ModelElement-travelers door het model heen gaan. Een voorbeeld van een dergelijke weergave is te zien in Figuur 4.3 & 4.3. Deze figuren zijn het best te bekijken in de PDF, daar er dan ingezoomd kan worden. Tevens is dit dus een weergave van hoe het model door de BDD geinterpreteerd zal worden. Deze klasse is puur ontworpen om in de ontwerpfase visuele feedback te hebben over hoe het model geanalyseerd wordt. Op vergelijkbare wijze kan er ook een graaf worden gecreëerd die alle variabelen en hun onderlingen verbanden toont.
Pagina 13
Hoofdstuk 4
Conclusie In de vorige hoofdstukken is uitgeweid over verscheidende dingen. Het probleem is aangeduid, zijnde een model gedreven testtool die naar mate het model groter wordt aanzienlijk complexer wordt. Er is gekeken naar wat een mogelijke oplossing zou zijn om dit tegen te gaan. We hebben uiteindelijk voor een van deze oplossingen gekozen om deze gedurende een twintigtal weken uit te werken. Dit idee is hierboven uitgelegd, tezamen met een uitweiding hoe deze oplossing binnen de code van NTA uitgevoerd dient te worden. Uiteraard zijn er ook nog subtiliteiten die niet in dit rapport beschreven zijn, daar deze zichzelf wijzen wanneer iemand de code zou doornemen.
4.1
Tijdsbesteding
Gedurende de eerste weken heb ik mij bekend gemaakt met mijn werkomgeving en NTA. Ik heb eerst als gebruiker met NTA kennis gemaakt om een idee te krijgen van de functionaliteiten van NTA. Hierbij was ik ook zeer geholpen door de tutorials geschreven door Daan van Beek, die zowel diende om mij bekend te maken met het systeem als documentatie, en een goed handvat om de werking van het systeem te doorgronden. Gedurende deze weken hebben we ook in overleg de exacte opdracht vorm gegeven. De contouren van de opdracht waren reeds tijdens onze eerste gesprekken voor aanvang van de stage bepaald. Om bij de exacte invulling als stagair ook meer mee te kunnen denken was een eerste kennismaking met NTA echter onmisbaar. De weken hierna heb ik literatuur gelezen met betrekking tot model driven testing, en BDD’s. Verder heb ik een aantal papers over JTorx bestudeerd. JTorx is een model driven test-tool, ontwikkeld door Axel Belinfante. Met deze tool ben ik reeds bekend via een vak dat ik heb gevolgd in het kader van mijn master, en het leek mij nuttig deze tool nogmaals te bekijken in het kader van mijn huidige opdracht. Gelijktijdig ben ik begonnen met een raamwerk om met behulp van JavaBDD van een graaf een BDD te kunnen maken. Later ook met de toevoeging van variabelen, stacks, transitierelaties en een methode om een pad te bepalen gegeven een beginnode en één van de bereikbare nodes die met behulp van de transitierelaties te bereiken is. Na dit raamwerk ben ik begonnen met het ophalen van informatie uit het model. In eerste instantie met behulp van vele extra (nieuwe) functies binnen het bestaande model. Later met behulp van "Travelersëen methode die erg op het bekende visitors-pattern lijkt. Waarbij het model gedecoreerd werd met klasses waar de verkregen informatie in opgeslagen werd. Hierna is er nog een aantal weken nodig geweest om de statische analyse van variabelen correct te implementeren, en nog enige tijd om pointers te kunnen analyseren. Een veelvoud aan weken is vervolgens besteed aan het verkennen van for-loops. Eerst door deze binnen het model uit te vouwen. Later door deze op een andere manier te verkennen met behulp van de travelers. Dit zorgde echter weer voor de nodige complicaties in het creëren van de BDD. Rond dat punt was echter de tijd voor mijn stage inmiddels ten einde gelopen. Reste mij enkel nog verslaglegging en een (interne) presentatie. Bij de presentatie heb ik de inhoud van dit project en de behaalde resultaten toegelicht. Ook heb ik toen een aantal mogelijk in de toekomst te volgen ideeen besproken, waaronder de haalbaarheid en wenselijkheid voor het afronden van deze benadering.
4.2
Behaalde resultaten
Helaas is het niet gelukt gegeven de tijd die voor de stage stond de gehele opdracht af te ronden. Gelukkig hebben we wel alsnog nuttige resultaten kunnen behalen. Allereerst kunnen we met de statische analyse nuttige informatie over het model extraheren. Deze informatie kan worden gebruikt voor de verkenning van het model, zij het met behulp van BDD’s of op een andere manier. Ook kunnen er door de traveller-klasses makkelijk bepaalde functionaliteiten aan NTA worden toegevoegd. Deze functionaliteiten waren voorheen al bedacht en gewenst verklaard. Het implementeren van deze functionaliteiten zonder het traveler-raamwerk kosten echter dusdanig veel tijd dat deze onderaan de featurelijst waren Pagina 14
beland. Een feature waar men aan kan denken is bijvoorbeeld opzoeken waar een variabele exact gebruikt wordt, en wat de impact is wanneer een gebruiker een variabele zou wijzigen. Momenteel is het verwijderen of aanpassen van een variabele een zeer precaire klus, gezien de neveneffecten niet goed zichtbaar zijn. Men zou dus of op blind vertrouwen een variabele moeten aanpassen, of een volledige kennis van het model hebben. In de praktijk betekend dit dat in een dergelijk geval vaak een nieuwe variabele geïntroduceerd wordt. Dit zal in de toekomst een hoop legacy variabelen, en dus een onnodig grote state-space kunnen opleveren. Gedurende deze stage zijn er ook al een aantal bugs en onvolledigheden in NTA gevonden en opgelost. Ook kunnen we nu een (veel) betere schatting maken van de haalbaarheid om NTA een op BDD-gebaseerde test-advisor te geven. Indien dat het geval is zou ook het raamwerk voor de BDD generatie kunnen gebruikt worden als basis hiervoor. Het is echter discutabel of een op BDD’s gebaseerde advisor een wijze keuze is in retrospect.
4.3
Aanbevelingen
Indien dit gelukt zou zijn zou het een zeer efficiënte en misschien wel de beste oplossing zijn om een goed advies uit te brengen aan NTA. Het probleem is echter dat de implementatie perfect dient te zijn, dit omdat er anders geen enkele garantie kan worden gedaan over de verkenning van het model mocht de BDD een fout bevatten. De complexiteit van dit project is wellicht uit te drukken door te trachten een naam te bedenken voor wat de NTA2 eigenlijk is. Het is een test guidance advisor voor een model based testing tool, gebaseerd op het verkennen van een model van het model middels een BDD. Misschien wel een: "BDD-based meta-Model Exploration based Test Guidance Tool for a Model Based Test Tool" Ook al zou deze tool correct werken, dan nog zou NTA2 in sommige aspecten complexer zijn dan NTA zelf. Dit klinkt niet als een wenselijke eigenschap. Al helemaal niet wanneer in de toekomst het gedrag van NTA wijzigt, dit kan bijvoorbeeld door een uitbreiding van functionaliteiten komen, of door de introductie van een extra NodeType. Maar ook iets simpels als een bug-fix kan ervoor zorgen dat het gedrag van NTA2 niet meer overeenkomt met NTA. Wat zou vereisen dan iemand deze functionaliteit dus ook in NTA2 aanpast.
Voltooiing van NTA2 Daargelaten dat de volledige correcte implementatie van een BDD-based Test advisor nog een aanzienlijke hoeveelheid werk zou betekenen. Mede doordat NTA nog wat ambiguïteiten bevat, verwacht ik dat NTA nog wel een aantal verassingen in petto heeft die de vlekkeloze implementatie van NTA2 in de weg zullen staan. Met betrekking tot de implementatie van foreach-Nodes stel ik voor deze ook in de BDD te encoderen, zoals bij JumpAndReturns ook gedaan is. Het uitrollen van for-loops lijkt een nodeloos ingewikkelde zaak te worden, ondanks dat dit op het eerste gezicht eenvoudig lijkt.
Gebruik van een bestaande modelchecker Een andere optie is om de verkregen informatie van de statische analyse in een model te stoppen dat door een traditionele modelchecker kan worden verkend. Persoonlijk lijkt mij dit geen heel goed idee. Dit omdat een volwaardige modelchecker NTA een stuk complexer maakt en dat nog steeds al het gedrag van NTA een vertaalslag dient te maken van NTA-model naar een andere modelleertaal. Daargelaten dat deze modelchecker bounded reachability checking op een manier implementeert die voor ons doel bruikbaar is.
Test Guidance op basis van eerdere verkenningen Ondanks dat een benadering met test-guidance op basis van (bounded) verkenning van de state-space waarschijnlijk het beste advies genereert denk ik dat in de praktijk een andere keuze handiger is. Momenteel verkend NTA heel oppervlakkig door te kijken of de aangrenzende nodes al zijn bezocht, en kiest de helft van de tijd voor de minst bezochte node. Om te zorgen dat wel elke node eventueel gekozen wordt zal NTA de andere helft van de tijd een willekeurige richting kiezen. Ik denk dat wanneer in deze oppervlakkige keuze de huidige waarde van de variabelen mee wordt genomen, welke verkregen kunnen worden met de statische analyse, dat er al een iets betere keuze kan worden gemaakt. Een grotere verbetering verwacht ik wanneer de coverage van het model centraal wordt opgeslagen. Op het moment dat er getest wordt zal NTA namelijk met meerdere instanties tegelijkertijd draaien. Ik denk dat wanneer van al deze instanties centraal wordt bijgehouden waar ze zijn geweest, dat er vanuit die centrale plek een betere en snellere coverage bereikt kan worden. Deze server zou dan ook kunnen meewegen in de te kiezen richting voor NTA. In plaats van 5 instanties die allemaal op vergelijkbare Pagina 15
manier door het model gaat zou de server de verschillende instanties kunnen sturen om gezamelijk het model te verkennen. Met behulp van de statische analyse zou op de server van te voren al kunnen worden bepaald of een bepaalde node wel of niet bereikbaar is, dit zou onnodig verkennen kunnen minimaliseren. Ook zou deze server verdachte plekken in het model in kaart kunnen brengen. Dit zijn plekken waar NTA of nooit komt, of maar een enkele keer. Dit kan meewegen in de beslissing om deze plekken te verkennen. Wanneer op een dergelijke manier het model wordt verkent zal dit zorgen voor: een minder complex systeem voor de test-advisor dan de BDD-oplossing Een robuuste verkenner die grotendeels ongevoelig is voor de interne werking van NTA. Tenslotte hoeven we niks te weten daarvan, we sturen enkel op basis op verkregen data over het bezoeken van locaties. En hiervoor zouden reguliere algorithmen kunnen worden gebruikt voor het verkennen van grafen. Ik denk dat dit redelijk makkelijk te passen is binnen de huidige structuur van NTA. De complexiteit van de verkenningstactieken zou in eerste instantie tamelijk simpel kunnen zijn, maar zou eenvoudig uit te breiden zijn. In tegenstelling tot de BDD-oplossing, wat meer een alles-of-niets-benadering is. Tevens denk ik dat er dan ook verschillende verkenningstechnieken gebruikt kunnen worden door verschillende instanties van NTA.
Pagina 16
2637
2639
2638
2635
2636
1649
2633
1603 2231
2632
2227
1602 730 726 1601
2631
2643
669
2230 2640
725 731 1999
1600
2000
2642
1588
664
724
732
665
2001
1599
662 1590
1595 1596 663
668
666
1594
1679
729 660
646 1606
1587
723 1997 2037
1214 1216 1591
667
2027 1215
1607
733
661
1658
751
1592
722
1636 1584
1597
721
3
1660
1653 711
712
1644
734 1678
720
1639 1645
3
1593
3
1598
713
1608
1585
2026
719
1586 998
1609
670
645
1610
735
2083
1651 1577 688
1611
1628
2082
2641
1582
1576
671
2084
2092 718
1575
644
1629 2091 687
2081
672
1656 1650 4
1572 2069
2134
2068 698 1633
2065 4
1573 1564
728
1574
1632
2080
1569 2135 4
525
1580 706
643
1578
686 2066
1567
589 717
1565
1562
2062 2061 2
1561
699
524
2060 748
2063
2138 591
2137 1666 522
2067 674
2097
528 2096
742
727 2136
642
700 685
260
2094
2139
885
1084 743 738
968
2093
2100 592
1065
702
675
4
529
261
744
2074
884
1085
641
2073
2047 684
2064
886
2088 2089
2057
962
883
964 707
593
2046
590 264
530
961
1086
3 3
969
677
2043 2059
875
2070
963
566 2 676
2044
2078 2
887
680
2098 2077
2076
2071
3
882 2045
1466
2127
544
2075
992
958
959
878 965
879
2106
2107
2072 2052
966
2051 740
736
563
541 2
876
3
739 877
542
564
543
888
2101 657 1641 1501
2133
2041
960 3
873
737
579
1254
1642
565
538
1500
1450 874
1665 2038
656
400 889
1481
1643
1451
1664
295 956 2055 1449 1100
401
296
1499
1109
578 294 872
1663
648
1110 655
1465
300
1662 2002 653 577
442 2
575 1661
953
1103
372
3
2005
957
443
1448 955 1094
576
871
1486 1508
441
892 580 651
1497
574
649
1498
2429 1489 628
2003 650
1473 1472 1496 1262
1
2430 1317
373
440 1491
1255
1492 2431 1111
290 647 1467
2 1488 583
870
1259 3 2432
2004
652 852
654 1493
439
1495
582 2
2441
581
444
2442 1469
1470
2
1434 1476
1318
2
2
1316 1478
2
3 1221
1475
438
1477 1435
1260
949
1494 869 106
107
1374
1485
461
1
1337 2
460
2
1506
1
1 1388
1320
1
2
1375
952
1338 1502
1319 2
584
1373
994
2 1
2 1444 1333 1387
1
1378 1507
1294 1366
1365 2 1342
1296 1 1484 868
1386 1
1264 3
1479
1 1
1
573
881
1290
914
1
1357
1474 1483
1289 3
1512
1462 1358 1377 1340
3
1443
3
921
913
2 1321
2 863
1282
3 1295 332
437
1271
328 1278
459 1288
2440
1368
1439 2
2
1097 1297
1359
864
912
947
1433
860 948 1261
2 535 558 1487 1345
446 1348
1427 1347 435
1362
1363
865
297 457 1
2
859
1
1291
1329
1328
854
880 1445
3
1
1431
279
278
285
280
3
1447
3
1327
331
1252 862
1371
1298 1331
2213 587
967
1385
867
464
855
2207
1350 3 1346
2296 1428 2212
2267
1263
1314
1429
1293 1440 1090
856
1461 2302
1098
2281 2279
534 306
1356
2209
2268
469
559
833 1241
2439
453
2278
1299 298
2276
2303 2275
866
857
2205 2271 2292
2288
1384
433
2272
2301
2289
2286
1031
2413
2273 2304
120
831 1430
2266 2210 2214
2280
2298
449 434 1 2287
2269
465 1302
858
2290 2277 2 2206
2300
2307
2297
2 830 3
2412 307 2414
3
2215
832 2
2299
2 3
2274
1242
2305
2
2265 2291 309
322
1096
1099 308
3
537
3
2295
1382
3
2203 2211
560 303 2208 919
2015
2216 3 2204 2270
2 2201
2264 2
1030
1026 2 1 1 2 1 1
3
3
320 313
1313
1024 1025
1243
1070
2016 316 834 1239
432 327
2 835
431 2262
1
2
837
2221
836 1463
2259 2
1
3 1460
2
1021
1092
2
1038
2258 851
1244
1240
2022
2 1069 85
1311
2014
116
1068
2219 1659
2217
429 2261
1062
1 159 1125
2702 2260
1028 2701
2703
2013
1020
84
334
1067
1022
2704
1131
546 1039
2705
824
1442
15
1010 1042 87 2 319
2196
1037 2406
2257 2220
2218
2405 1
2699
1 2709
2410 1009 1459
1127
161
821
2696
2698
823
2
822
1033
1008
2263 2409 2513
86 2695 475 850
1 2408 1018 2693 2500
1023
2717
842
2514
2711
2694
1034
2438 2256
547 2
416 1458 2501
1017
1132
1041
843 2710 840
2199
2198 311 474 1
2499
2707 2019
838 2502
2407 1453 185
81
825
2731
2713
2740 1129
1177 548 2660 2737
2255
1083
312
164
1457 124
2738
2503
839
2739
1040 2285 346 82
568
2736 347 345
894
549
80
2672
1538
354
353
2659
2741
551
348 356
357
844 363
358
92
550
2463
1994
1514
1533
344 473 163 895 2197
1
1951
2251
1
349
2673
2021
364
1530 569
1454
1513
359
83
2018
1
90 572 2683
1014 361
1005
1015 571 1104
350
360 184
570
1016 1995 89
336 16
1036 1133
91 88 14 2 980 1006 1052 1108 2250
1996
352
2729
552
1007
4 793
2 1105
2020
2151
1399
1107
900
1106 186
792
2
898 2728 2310 899
2
1952
1169
770
2
2150
1044
1056
755
417 402
788 2012
165
760 787
2727
786
2
771
2726
2
789
2 2149 785
166
790
2312 1987
1993
784 1168
1931
1011 617
1170
772 479
1057 2724
2311
1991
1012
1049
2434
1045 162
783 2006
1989 3
3
773
1013
3
3
761
2
75
762
1955
1050
2435
1990 4
18 4
774
1048
2
781
1953
777
1186
1182
1932 480 1954
1405
415 2008
782
764
2
775 2007 2294
2 2147 284
778
283
282
2023
281 74 2313
779 1047
780 1165
1941
1950
1046 763
776 2148
1171 477
1935
183
625 2146
56 2
55 62 626 2017
2 640 1080
1948 2 1934 2142 2024 1
765
1936
2551
167
63 1712
1942
1939 481
174
518
2175
2552
2 618 61 1938
1943 2172
187 983
177
2
981 999 2714
65 1933 2 410 2716
1000 60
403
1940
1135
624
1 2720
57
1172
1 2719
213
24
1944
210 212
175
211 209
2715 1937
169
2141
506
208
1079 59
207
2145
58
22
206
23
170
2173
205 168 511 516 2718
176
2 2284
2415
768
2168
203
2152
408
202
507
498 188
404 2723 2174
759
476 1185
1188 66 242
2159
2433
201
1173
413
189
2144 1136
510 508 769
1
2232
2244 2170
405 509
200
2721
2157 3
2556
2034 2153
407
2171
2158
472
2169 2155
2722
519
3
2140
758 3
2036 512
2555 198 2143 2418 406
2166
1071 3
637 1174 190 2156
196 2571
503
484
2245 766
2249
1181
409 1137
757
192
2226
195 2191
2193
199 193 496
2246
1003
2233
229 533
1004
194 1490 1093 4 1089
368
2180
1088
639
4 1087
2283 370 369
2190 2592
2189
2192
2248
1175
2247
1826
1176
2188
2176
2179
2195
2033
2165 217 620 1134
4 2424
485
228
2035 2181
767
2177 2222 1890
2282
2178
2554
1150
2225
2183
1179 499
1072 2182 227
486
2185
2187 819
2553
2167
2028 1160 2223
1
2242 2224 1183 600
2194
4
1
2423
2573 5
2184
1713
2186
623 218 487
226
4 488 490
1194
1078
1091
1141
1195
2029 219
818
1
1148
2243 495
225 1828
2030
1184 1151
5
1162 1928
1
1193
220
1892 1192
224
1142 2419
2417
1
621
1159
1888 2583 2241 221
494 223 222
1145 491
622 619 1708 2575
1147 2032 4
1077 1161 1191 1717
1190
2578
493 1073 492
3
1143
3
2234
1926 2420
1152
1146
1927
2426 2031 3 1076
1196
2581 597 1158 598
2586
1075
2240
1204
1631
2580
2587
2582
1893
2238 2421
2422
2237
2576
1957 1822
2630
1153 1925
2416
2425
2 2
1157
2235
1956 2239
1197 2579 1705
1706
1700
1154 4
2
1202
2236
1704 1801
1701 1894 595
596
1895
1823
377
1703
1842
2577
2
1779
1817
1156
1702 1923 1924
1821
1777
1778
1155
4
2 1198
1845
1843
382
1721 2010
1200
1716
1846
1844
1820
1810
1715
1203 1833
1847
1913
1922
2
2
2
1199
1834
1818
3
1725 1819 1781
1780
1724 1880 1683 1201 1813
1684
1809
1782
1835
1921
1786
1811
1815
1785
1914
1802
1920 1915 1812
1836
1783 1804 1841
1806
398
1805
1838 1886
1814
1807
1808 1803
1837
1784 1919
1840
1881
1792
1916
911
1839
1799 1798
1854
1793 1918
1797 1887
1917
1883
1790
1800
1885 1788
1791 1882
1796
1872
1795
1789 1884 1787
1794
1878 1855
1848
820
1850
1852
1862
1864
1849
1870 1873
1879
1851
1853
399
1865
1871
1874 1877 1856
1875
1868
1876
1869
1867 1866
1863
1857
1858
1860
1861
1859
383
985
385
388
389
384
390
391
982
392
796
1237
3
1235 3 1238
1227
1231
394 1228
397
456
605 395
606 608
602
1119
798
603
616
604
607
613
1118
802 615
807
614
1081 610
612
808
611
809
797 1121
810
609 814
799
811
815
1120 816 1115 812
1116
804 1114
813
1082 800
805
817
801
806
1113
1112
803
Figuur 4.1: Weergave van het NTA-model zoals verkend door NTA2
Pagina 17
name:
global.fieldPermissions.language
default: persistent:
NO
static:
NO
referencedto:
YES
name: name: name:
name:
NO YES
persistent:
NO YES
name:
persistent:
NO
persistent:
NO
static:
YES
static:
NO
referencedto:
NO
referencedto:
NO
default:
name:
global.userOeveren:host
name:
default: name:
global.userBlok:created
name:
default:
local.quickLaunch.carrier:badgeID
persistent:
persistent:
NO
referencedto:
static:
NO
referencedto:
NO
NO
static:
name:
local.personVehicle.person
NO
static:
NO
referencedto:
persistent:
local.createEmployee.changeCar
persistent:
NO
NO
static:
YES
NO
referencedto:
NO
NO
NO
static:
NO
referencedto:
true
false
true
false
true
global.fieldPermissions.freeTime
name:
default: persistent:
name:
NO
static:
NO
referencedto:
YES
local.createEmployee.carrier:firstName
global.fieldPermissions.freeString:value
default:
name:
testString
persistent:
name:
YES
NO
static:
static:
NO
referencedto:
NO
global.user:monitorEventMonitorPhotoEvents
static:
NO
referencedto:
NO
NO
name:
NO
static:
NO
NO
referencedto:
NO
name:
global.bulkEdit.bulkMixed2:blocked
name:
default:
referencedto:
YES
static:
NO
referencedto:
persistent:
NO
name:
global.bulkEdit.bulkVisitor3:blocked
persistent:
NO
NO
static:
NO
NO
referencedto:
NO
NO
static:
NO
referencedto: false
true
true name: local.personVehicle.replaceToken:setIdentifierTypeTo
persistent:
global.userBosse:created
name:
global.bulkEdit.bulkMixed3:created
persistent:
NO
referencedto:
static:
NO
NO
persistent:
NO
referencedto:
name:
NO
static:
NO
static:
NO
referencedto:
NO
referencedto:
NO
default: default:
referencedto:
NO
name:
NO
persistent:
NO NO
referencedto:
NO
NO
NO
static:
NO
referencedto:
name:
NO
YES
true
true
false name:
local.httpLoginProcedure.username
default:
administrator NO
global.fieldPermissions.freeBoolean:readable
name:
default:
global.fieldPermissions.freeDateTime:readable
name:
default:
referencedto:
global.fieldPermissions.personnelNo
NO
persistent:
NO
persistent:
NO
static:
NO
static:
NO
static:
NO
NO
referencedto:
NO
referencedto:
NO
persistent:
persistent:
NO
static:
NO
referencedto:
YES
YES NO
name:
NO
local.personVehicle.bulkListContractor
name:
static:
NO
referencedto:
NO
default:
static:
NO
referencedto:
NO
name:
default: NO
static:
NO
true
referencedto:
YES
false
name:
global.bulkEdit.bulkVisitor3:created
name:
default:
global.fieldPermissions.freeString:writeable
name:
default:
persistent:
NO
static: referencedto:
global.fieldPermissions.department:mandatory
name:
default:
persistent:
NO
NO
static:
NO
referencedto:
global.fieldPermissions.freeTime:mandatory
static:
NO NO
NO
static:
NO
referencedto:
persistent:
referencedto:
static:
NO
referencedto:
NO
static: name:
global.bulkEdit.bulkEmployee2:blocked
name:
global.fieldPermissions.language:mandatory
name:
NO
persistent:
NO
persistent:
NO
persistent:
NO
true
static:
NO
static:
NO
static:
NO
static:
NO
static:
NO
false
referencedto:
NO
referencedto:
NO
referencedto:
NO
referencedto:
NO
referencedto:
NO
name:
NO
persistent:
NO
static:
NO
static:
NO
default:
true
global.fieldPermissions.freeStringLookup:readable
true
true
referencedto:
YES
referencedto:
NO
true
false
false
name: name:
name:
global.fieldPermissions.freeDate:writeable
name:
default:
name:
global.bulkEdit.bulkEmployee2:created
local.personVehicle.replaceToken:setBadgeNumberTo
persistent: static:
NO
NO
referencedto:
YES
NO
persistent:
NO
persistent:
NO
persistent:
NO
persistent:
NO
static:
NO
static:
NO
static:
NO
static:
NO
default:
NO
referencedto:
NO
referencedto:
NO
referencedto:
NO
referencedto:
NO
persistent:
true
true
false
name:
name:
global.bulkEdit.bulkEmployee3
persistent:
NO
static:
NO NO
name:
persistent:
false
name: freeTime
local.createEmployee.findFreeFieldDefinition
name:
global.bulkEdit.bulkEmployee3:blocked
persistent:
NO
YES
default:
static:
NO
default:
NO
persistent:
NO
persistent:
NO
referencedto:
NO
persistent:
NO
NO
static:
YES
NO YES
static:
NO
static:
NO
referencedto:
NO
referencedto:
NO
referencedto:
NO
name:
true
NO
name:
NO
default:
referencedto:
NO
referencedto:
NO false
local.createEmployee.changeContractor:setDefinitionId
persistent:
NO
static:
NO
referencedto:
NO
global.user:entranceEntranceProvideAccess
persistent:
NO
static:
NO
referencedto:
NO
global.AEPUAvailable true
name:
persistent:
NO
15:02
static:
YES
referencedto:
NO
NO
local.personVehicle.bulkCarrier3
name: name:
name:
persistent:
NO
referencedto:
static:
NO NO
default:
NO NO false
name:
NO
static:
NO
persistent:
NO
static:
NO
referencedto:
YES
name:
global.bulkEdit.bulkMixed1:blocked
name:
NO
persistent:
NO
persistent:
NO
YES
static:
NO
static:
NO
referencedto:
NO
referencedto:
NO
referencedto:
NO
default:
name:
NO
static:
NO
default:
NO
persistent:
NO
NO YES
value1 2013-09-14 testString true
name:
NO
persistent:
NO YES
name:
persistent:
false
freeString
name:
NO
static:
NO
referencedto:
NO
referencedto:
YES name:
NO YES
static:
NO
static:
NO
default:
NO
referencedto:
NO
persistent:
NO
static:
NO
referencedto:
NO
aeosrules
static:
NO
NO
referencedto:
YES
default:
static:
persistent:
NO
static:
NO
referencedto:
NO
global.bulkEdit.bulkContractor1
persistent:
NO
2014-08-21T16:01:21
static:
NO
15:02
default: persistent:
referencedto:
NO
NO
name:
name:
persistent:
NO
static:
NO
static:
NO
referencedto:
NO
NO
name:
local.personVehicle.assignToken
name:
default: NO
static:
YES
static:
NO
referencedto:
NO
referencedto:
NO
static:
NO
default:
NO true
global.bulkEdit.bulkVisitor2:blocked
local.personVehicle.unblockToken:setIdentifierType
name:
persistent:
NO
persistent:
NO
static:
NO
static:
NO
referencedto:
NO
referencedto:
NO
local.personVehicle.unblockCarrierRequest
name:
local.personVehicle.currentRequest:getId.VisitorInfo
NO
NO
static:
NO
static:
NO
referencedto:
NO
NO
referencedto:
default:
NO
NO
name:
name:
global.bulkEdit.bulkContractor2:created NO
persistent:
NO
static:
NO
static:
NO
default:
NO
referencedto:
NO
referencedto:
NO
persistent:
NO
static:
NO
referencedto:
NO
local.quickLaunch.mode
persistent:
NO
static:
YES NO
true
true
false
false
name:
static:
NO
referencedto:
NO
static:
NO
local.personVehicle.blockCarrierRequest:setCarrierId
name:
name:
persistent:
NO
static:
NO
NO
referencedto:
NO
default:
referencedto:
NO true
local.personVehicle.carrier:attachment
local.personVehicle.carrier
persistent:
NO
static:
NO
referencedto:
NO
name:
persistent:
NO
persistent:
NO
persistent:
NO
static:
NO
static:
NO
static:
NO
referencedto:
NO
referencedto:
NO
referencedto:
NO
false
default:
NO
persistent:
NO
NO
static:
NO
referencedto:
NO
referencedto:
name:
NO
name:
default:
NO
persistent:
NO
persistent:
NO
NO
static:
NO
static:
YES
referencedto:
NO
referencedto:
NO
name:
static:
NO
static:
NO
false
referencedto:
NO
referencedto:
NO
referencedto:
NO
NO NO
referencedto:
YES
name: local.personVehicle.replaceToken:setIdentifierTypeFrom
name:
default:
local.quickLaunch.host
local.personVehicle.currentRequest:setIdentification
persistent:
persistent:
NO
referencedto:
static:
NO
NO
referencedto:
NO
static:
referencedto:
NO
referencedto:
NO
persistent:
NO
NO
YES NO
global.user:monitorPresenceViewPresenceVehicles
name:
local.personVehicle.currentRequest:setLastName
name:
default: NO
persistent:
NO
static:
NO
static:
NO
NO
referencedto:
NO
persistent:
YES
static:
NO
NO
referencedto:
NO
local.personVehicle.unblockToken:setBadgeNumber
name:
name:
persistent:
NO
persistent:
NO
NO
static:
NO
name:
NO
referencedto:
name:
NO
persistent:
NO
static:
NO
static:
NO
referencedto:
NO
referencedto:
NO
name:
local.visit.findVisit:getId.VisitInfo
name:
local.personVehicle.carrier:mode
default:
name:
local.personVehicle.bulkMode
name:
NO
default:
referencedto:
NO
persistent: static: referencedto:
NO
default:
persistent:
NO
persistent:
NO
persistent:
NO
static:
NO
static:
NO
static:
YES
referencedto:
NO
referencedto:
NO
referencedto:
NO
static:
NO NO
name:
true
default: persistent:
referencedto:
NO
referencedto:
referencedto:
NO
NO
default:
NO NO
referencedto:
NO NO
name:
NO
name:
persistent:
NO
static:
persistent:
NO
static:
NO
referencedto:
NO
NO NO
name:
NO
NO
default:
NO
persistent:
name:
name:
NO
default:
global.user:personVisitorSearchVisits
name:
persistent:
NO
persistent:
NO
static:
NO
static:
YES
referencedto:
NO
referencedto:
NO
default:
false
name:
NO
persistent:
NO
default:
static:
NO NO
local.createEmployee.findTemplate:getId
true local.personVehicle.carrier:ID NO
static:
NO NO
NO
static:
NO NO
NO
static:
NO
NO
referencedto:
NO
referencedto:
NO
name:
NO
local.createEmployee.carrier:licensePlate
local.createEmployee.carrier:identification
persistent:
NO
static:
NO
referencedto:
NO
default:
NO
persistent:
NO
static:
NO
referencedto:
NO name:
local.personVehicle.carrier:visit
NO
static:
NO
referencedto:
referencedto:
NO
NO
persistent:
NO
static:
NO
static:
NO
referencedto:
NO
referencedto:
NO
name:
local.createEmployee.changeEmployee:setId
name:
local.dashBoard.carrier:mode
default:
true
referencedto:
NO
persistent:
NO false
NO
YES
default:
NO
NO
referencedto:
2013-09-14
static:
NO
NO
name:
default:
false
false
default:
persistent:
local.mainButtons.widgets.detailedEvents
static:
local.personVehicle.findIdentifierType NO
NO
name: default: persistent:
NO
static: name: default: YES
default:
local.createEmployee.addCar:getId
default:
referencedto:
default: persistent:
local.quickLaunch.carrier:lastName
static:
persistent:
NO
persistent:
NO
persistent:
NO
YES
referencedto:
name:
NO
static:
name:
NO
NO
static:
NO
local.personVehicle.replaceToken:setReason
default:
NO
YES
NO
NO
persistent:
static:
static:
NO
referencedto:
local.createEmployee.findDepartment:getId
persistent: referencedto:
persistent:
persistent:
NO
local.personVehicle.removeCar
default:
NO
name:
NO
local.personVehicle.carrier:host
local.personVehicle.carrier:badgeID
name:
global.fieldPermissions.language:value
default:
name:
local.personVehicle.blockToken
default:
persistent:
NO
persistent:
NO
persistent:
NO
static:
NO
static:
NO
static:
YES
referencedto:
NO
referencedto:
NO
referencedto:
NO
default:
2013-09-14
default: persistent: referencedto:
persistent:
NO
global.fieldPermissions.freeDate:value
referencedto:
local.dashBoard.carrier:blocked
name:
NO
NO
name:
local.personVehicle.findBlockReason name:
local.personVehicle.findIdentifierType:getId
static:
name:
name:
NO
YES
persistent:
true
default:
local.mainButtons.widgets.presence
freeDate
freeDate
default:
false
local.personVehicle.removeEmployee
default:
local.createEmployee.changeCar:setId
global.fieldPermissions.freeDate:name
referencedto:
global.bulkEdit.bulkVisitor1:blocked
static:
NO
name: default: persistent:
default: name:
referencedto: NO
name:
NO
NO
default: local.personVehicle.findBlockReason:setName
static:
referencedto:
default:
NO
persistent: name: persistent: referencedto:
static:
NO
static:
true
local.createEmployee.carrier:middleName
default:
NO
NO
default:
2014-08-21T16:01:21 NO
NO
persistent:
YES
true global.user:monitorEventMonitorTextEvents
YES
referencedto:
global.fieldPermissions.freeBoolean:value
default: static:
name:
global.fieldPermissions.freeDateTime:value YES
NO
static:
name:
NO
referencedto: NO
local.personVehicle.currentRequest:getId.CarInfo
NO
static:
NO
local.personVehicle.reloadCarrier
static: referencedto:
Department
static:
persistent:
NO
persistent: name: persistent:
NO
global.fieldPermissions.department:name
static:
Department
persistent: referencedto:
local.createEmployee.currentRequest:setMiddleName
local.personVehicle.assignToken:setCarrierId
default: NO YES
name: default: persistent: referencedto:
local.personVehicle.blockToken:setIdentifierType
default: NO
static: referencedto:
local.personVehicle.blockCarrierRequest
static:
NO
false
YES
default:
name:
persistent:
false
NO
true
freeStringLookup
name:
default:
referencedto:
true
NO
static:
static:
NO
name:
global.fieldPermissions.freeDate:mandatory
global.carrierVehicle:created
global.fieldPermissions.freeStringLookup:name
default:
referencedto:
NO
false
name:
false
freeStringLookup
name:
true
NO
referencedto:
name:
NO
false
NO
NO
referencedto:
NO
static:
referencedto:
NO
YES
name:
referencedto: NO
NO
freeBoolean
default:
default:
local.createEmployee.carrier:lastName
static:
NO
static:
freeBoolean
NO
persistent:
local.createEmployee.addEmployee:getId
referencedto:
persistent:
true
NO
name:
static:
NO YES
NO
false
global.userBlok:host
persistent: referencedto: global.fieldPermissions.freeBoolean:name
default: persistent:
NO
static:
NO
default:
default:
global.bulkEdit.bulkContractor1:blocked
local.createEmployee.changeEmployee:setDefinitionId
NO
Carrier Replacement name:
name:
NO
default:
static:
Bosse
persistent:
NO
static:
global.bulkEdit.bulkEmployee1:blocked
persistent: static:
local.createEmployee.currentRequest:setLanguage
default:
2014-08-21T16:01:21
NO
persistent:
default:
NO
referencedto:
global.fieldPermissions.freeString:readable
local.createEmployee.addVisitor
persistent:
name: default:
name:
static:
NO
static:
referencedto: local.createEmployee.currentRequest:setFirstName
persistent:
referencedto:
default: persistent:
persistent: referencedto:
default:
referencedto:
local.personVehicle.assignToken:setIdentifierType
default:
default:
referencedto:
default:
NO
local.createEmployee.currentRequest:getId
default:
NO
default:
persistent: referencedto:
NO
persistent:
referencedto:
name:
NO
true false
YES
name: NO
static:
NO
static:
true
NO
local.createEmployee.changeEmployee
persistent: referencedto:
name: default:
NO
static:
NO
default:
NO
global.fieldPermissions.freeString:mandatory
default:
persistent: NO
static:
local.quickLaunch.carrier
local.createEmployee.currentRequest:setDepartmentId
false
local.createEmployee.changeContractor
referencedto:
local.personVehicle.carrier:blocked
default: name: name: persistent: referencedto:
NO
value1
default:
default: static:
NO
name:
NO true
persistent:
NO
NO
NO
local.dashBoard.carrier:visit
PersonnelNr
local.createEmployee.currentRequest:setLastName
NO
NO
name:
NO
static:
true
local.personVehicle.carrier:identification
YES
NO
NO
default:
name:
Bosse
YES
static:
value1
default: global.userBosse:lastName
static:
PersonnelNr
persistent:
freeDateTime
name: default: persistent: referencedto:
local.createEmployee.currentRequest:setIdentification
NO
static:
persistent:
global.fieldPermissions.personnelNo:value
referencedto:
default:
NO
global.fieldPermissions.freeStringLookup:value
static:
YES
local.quickLaunch.host:host
static: referencedto:
static:
persistent: name: default: persistent: referencedto:
freeDateTime
name: persistent:
persistent:
NO
true
false
global.fieldPermissions.freeDateTime:name
static: referencedto:
NO
true
static:
true
true
name: default: persistent: YES
local.personVehicle.withdrawToken
NO
global.fieldPermissions.personnelNo:name
YES
persistent:
false true false
NO
static:
NO
name:
name:
referencedto:
false
NO
default:
default:
persistent:
global.fieldPermissions.language:readable
NO YES
false
local.personVehicle.bulkCarrier1:created
static:
persistent:
referencedto:
name:
default:
clean
default: persistent: referencedto:
persistent:
static:
false
NO
global.bulkEdit.bulkContractor3:blocked
false
global.fieldPermissions.department:readable
NO
NO true
NO
referencedto:
persistent:
name:
NO
local.personVehicle.currentRequest:getId.ContractorInfo
NO
NO
static:
NO
default:
default:
name:
global.userBlok
default:
name:
YES
referencedto:
default:
NO
persistent:
NO
name: name:
NO
NO
persistent:
false name:
global.fieldPermissions.personnelNo:readable
referencedto:
local.createEmployee.changeCar:setDefinitionId
NO
static:
default: NO
YES
referencedto:
true NO
static:
NO
default:
persistent:
global.userOeveren:created
static:
NO
static:
NO
local.visit.removeVisitRequest
persistent:
NO
default:
name:
default:
persistent:
NO
YES
true
persistent:
name:
NO
static:
false
NO
default:
persistent: referencedto:
global.htmlEnabled
static:
name:
referencedto:
NO
local.personVehicle.replaceToken:setBadgeNumberFrom
default:
global.badgeXS23
default:
name: default:
persistent:
true
default:
default:
NO
name:
NO
referencedto:
NO
true
NO
clean
NO
referencedto:
NO
NO YES
default:
local.dashBoard.carrier
NO
local.createEmployee.addEmployee
static:
persistent:
static:
name:
static: name:
persistent: referencedto:
name:
referencedto:
name:
local.personVehicle.blockToken:setBadgeNumber
local.personVehicle.bulkCarrier3:created
default:
NO
name:
local.dashBoard.badge
static:
default:
referencedto:
local.personVehicle.visitSelected
persistent:
default: name:
NO
NO
name:
NO YES
name: default: persistent: referencedto:
NO
NO
static: referencedto:
NO
NO
false
persistent:
NO
true
NO
local.createEmployee.addCar
persistent:
name:
default:
false
false
NO
static:
NO
name:
NO
local.mainButtons.widgets.entrances
static:
NO
static:
persistent: referencedto:
NO
global.user:monitorPresenceViewPresencePersons
persistent:
name: name: default: persistent: referencedto:
NO YES
global.fieldPermissions.freeStringLookup:writeable
global.fieldPermissions.language:writeable
persistent:
NO
NO
false
static:
default:
NO
static:
default:
referencedto:
name:
default:
persistent: referencedto:
default:
name: local.createEmployee.addContractor:getId
persistent: referencedto:
NO
local.createEmployee.currentRequest
persistent:
default: name: default:
static: referencedto:
NO YES
false
name:
global.userOeveren
default: NO YES
NO true
NO
static:
default:
default:
local.personVehicle.removeVisitor
static:
NO
NO
default:
name:
NO
persistent: referencedto:
local.createEmployee.success
static: NO
static:
NO
NO
default: persistent: referencedto:
referencedto:
local.personVehicle.withdrawToken:setBadgeNumber
persistent: referencedto:
YES
local.createEmployee.currentRequest:setPersonnelNo
persistent:
YES
default:
static:
local.createEmployee.addCarrierAuthorizations:setCarrierId
512 name:
name: default: persistent:
default: persistent:
NO
static:
name:
NO
name:
true NO
name: name: name: persistent:
NO
static:
global.bulkEdit.bulkEmployee2
NO YES
NO
default:
true
testString
global.carrierVehicle
static: referencedto: global.userBosse
default:
referencedto:
persistent:
referencedto:
NO
true
name:
clean
clean
local.quickLaunch.badge
default:
NO
NO
false
persistent:
global.badgeXS86
static: referencedto:
name:
global.bulkEdit.bulkContractor3:created
NO
false
persistent:
default:
NO
false
default:
referencedto:
NO YES
static:
global.fieldPermissions.department:writeable name:
name: default: persistent:
static: referencedto:
persistent:
NO
2013-09-14
name: default:
default: NO
NO
persistent:
name:
persistent:
default:
persistent:
true
NO
static:
NO
referencedto:
true
name:
NO
name:
local.personVehicle.currentRequest:getId.EmployeeInfo
persistent:
NO
NO clean
clean
global.fieldPermissions.personnelNo:mandatory
static:
default:
default: NO
NO
referencedto:
global.badgeXS17
name:
persistent:
15:02
name:
local.personVehicle.withdrawToken:setIdentifierType
static:
NO
static:
NO
default:
referencedto:
value1
default:
name: persistent: referencedto:
false
NO
default: persistent:
NO
name: default: persistent:
2014-08-21T16:01:21
persistent:
NO
default:
referencedto:
name:
local.createEmployee.changeEmployee:setValue
value1
NO
true
NO
NO YES
testString
NO
static:
local.personVehicle.bulkCarrier2:created
default: persistent:
NO YES
local.personVehicle.badge
default:
global.bulkEdit.bulkEmployee1:created
persistent: referencedto:
referencedto:
name:
default: aeosrules "userAdministrator"
name: global.user:personVisitorSearch
clean
clean
"userAdministrator"
NO
static: referencedto:
2013-09-14 "userAdministrator"
NO
referencedto:
NO aeosrules
global.badgeXS59
default:
referencedto:
default:
referencedto:
local.httpLoginProcedure.password
YES
true
NO YES
NO
local.createEmployee.changeVisitor:setValue
default:
aeosrules
NO
clean NO YES
NO
static: referencedto:
persistent:
default:
name:
NO
NO
true
name:
NO
name:
persistent:
local.loginProcedure.password
NO YES
NO
static: referencedto:
global.bulkEdit.bulkMixed2
persistent: NO
global.fieldPermissions.freeBoolean:writeable
default:
NO
name:
referencedto:
NO
local.personVehicle.bulkCarrier2
default:
local.createEmployee.carrier
static:
NO YES
default:
NO
default:
name: default: persistent: referencedto:
local.personVehicle.removeContractor
persistent:
NO
global.bulkEdit.bulkContractor2
persistent:
static:
local.createEmployee.carrier:mobile
bulkEdit.bulkVisitor1 bulkEdit.bulkVisitor2 bulkEdit.bulkVisitor3
static:
NO
referencedto: NO
default: NO
static:
name:
clean
static:
default: persistent:
NO
true
bulkEdit.bulkMixed1 bulkEdit.bulkMixed2 bulkEdit.bulkMixed3
default:
name:
local.personVehicle.bulkListVisitor
name:
static:
global.fieldPermissions.freeDateTime:writeable
default:
false
NO
persistent:
false
name:
global.user:username
persistent: name:
NO YES
NO YES
referencedto:
name:
NO YES
NO
static: referencedto:
local.personVehicle.bulkListMixed bulkEdit.bulkMixed1 bulkEdit.bulkMixed2 bulkEdit.bulkMixed3
static:
NO
true NO
static: referencedto:
name:
name:
referencedto:
global.bulkEdit.bulkMixed1
referencedto:
default:
global.badgeXS96
persistent:
NO
default:
default: persistent:
NO
name:
NO
name: default: persistent:
local.createEmployee.addContractor
global.bulkEdit.bulkVisitor2
persistent:
NO
NO
static:
NO
default: persistent:
name:
default:
NO
global.bulkEdit.bulkMixed3
default: persistent:
NO
false
NO
name:
default:
NO
NO YES
NO
NO
clean
NO
local.personVehicle.bulkCarrier1
static:
NO
NO
static:
NO
default: persistent:
NO
static:
false
static:
static:
persistent:
referencedto:
local.dashBoard.replace
persistent: referencedto:
local.mainButtons.widgets.photoEvents
default:
static:
name:
true
NO
static:
NO
persistent:
persistent:
static:
local.createEmployee.carrier:created
NO
referencedto:
persistent:
true name:
NO
freeDate
global.bulkEdit.bulkVisitor1
referencedto:
NO
referencedto:
PersonnelNr
referencedto:
name:
NO
static:
true
name:
false
name:
global.bulkEdit.bulkVisitor1:created
default:
persistent: referencedto:
global.fieldPermissions.freeDateTime:mandatory
default:
true
true
NO
YES clean
name: NO
static:
referencedto:
testString
global.fieldPermissions.freeTime:writeable
name:
name: default:
NO
referencedto:
local.quickLaunch.replace
local.createEmployee.changeVisitor:setDefinitionId
persistent: referencedto:
persistent:
15:02 value1 2013-09-14
NO
true
static:
YES
freeStringLookup
referencedto:
2014-08-21T16:01:21
NO
NO
static: referencedto:
false
false
NO
referencedto:
true
static:
NO
2014-08-21T16:01:21 global.bulkEdit.bulkEmployee1
persistent:
NO
local.createEmployee.replicateMode
static:
NO
local.createEmployee.addCarrierAuthorizations:setTemplateId.TemplateAuthorisationOnline
persistent:
default:
false
name: default: persistent:
clean
persistent:
false
name: default:
default:
referencedto:
static:
default:
NO
referencedto:
freeTime freeDateTime
referencedto:
persistent: local.createEmployee.changeVisitor
static:
NO
clean
bulkEdit.bulkVisitor1 bulkEdit.bulkVisitor2 bulkEdit.bulkVisitor3
name:
name:
default: persistent:
Language NO
default:
default:
NO
"userAdministrator"
local.createEmployee.changeContractor:setValue
false
persistent:
NO
static:
global.badgeXS105
NO
NO
NO
default:
NO
true
true
persistent: referencedto:
name:
default:
NO
15:02
local.personVehicle.findBlockReason:getId
persistent: referencedto:
NO
static:
NO
freeBoolean
static:
local.createEmployee.currentFreeField:value
global.fieldPermissions.personnelNo:writeable
default:
false
persistent: referencedto:
referencedto:
name:
true
static:
local.mainButtons.widgets.upcomingVisits
default:
NO
NO
false
referencedto:
name:
NO
NO
clean
persistent: referencedto:
default:
true
default:
name:
YES
NO
true
persistent:
15:02
15:02
static: referencedto:
testString
global.fieldPermissions.freeTime:value
static:
global.badgeXS38
default:
true
name: default: persistent: referencedto:
NO
local.createEmployee.findFreeFieldDefinition:setName
global.bulkEdit.bulkEmployee3:created
default: name: default:
value1
default:
default: static:
NO
static:
name: name:
2013-09-14 name:
global.bulkEdit.bulkMixed3:blocked
persistent:
NO
default:
name:
2014-08-21T16:01:21
true
NO
NO
global.user:password
default:
local.personVehicle.replace
static:
Department
false
YES
name: default: persistent:
local.createEmployee.changeCar:setValue
false
static:
name: local.personVehicle.bulkList
persistent:
YES
referencedto:
freeTime
default:
NO
NO
referencedto:
NO
static: referencedto:
default: default:
persistent:
NO
true
static:
global.fieldPermissions.freeTime:name
static:
name:
clean
name: NO
static:
false
global.bulkEdit.bulkContractor1:created
name: default: persistent: referencedto:
local.createEmployee.findTemplate
NO YES
local.createEmployee.findFreeFieldDefinition:getId
persistent: referencedto:
NO
persistent:
name:
name: default:
NO
global.fieldPermissions.freeStringLookup:mandatory
persistent: referencedto:
global.bulkEdit.bulkContractor3
static:
default:
true
false
local.personVehicle.badge:ID name:
NO
default:
NO
NO
NO YES
default:
NO
NO
NO
default:
NO
NO
static:
static:
NO
static: referencedto:
static:
local.createEmployee.currentRequest:setLicenceNumber
referencedto:
global.bulkEdit.bulkVisitor3
default:
local.createEmployee.currentRequest:setMobilePhoneNo
persistent: referencedto:
persistent:
static:
persistent:
NO
persistent:
default:
default:
referencedto:
default:
local.personVehicle.findContractor
default:
dashboard
name: name:
default:
global.bulkEdit.bulkVisitor2:created
name:
YES
default:
false
false
name:
clean
referencedto:
YES
referencedto:
local.personVehicle.blockCarrierRequest:setReason
default:
default:
default:
global.badgeXS46
default:
NO
global.bulkEdit.bulkMixed1:created
true
name:
NO
NO
referencedto:
name: persistent:
false
NO
static:
dashboard
static: name:
NO
local.createEmployee.carrier:mode
persistent:
global.currentInterface
persistent: global.fieldPermissions.freeStringLookup
persistent:
default: global.fieldPermissions.freeDate:readable
local.personVehicle.success
default:
default:
NO
default:
NO true false
default:
global.userReplaceOnly
referencedto:
name:
NO
true false
default:
name:
"userAdministrator"
NO
NO
true false
persistent:
persistent:
NO
default:
persistent:
NO
true false
persistent:
default:
referencedto:
NO
static:
NO
name:
name:
persistent: global.userReadOnly
"userAdministrator"
default:
name:
name:
local.createEmployee.currentFreeField:DefinitionId
referencedto:
NO YES
default: "userAdministrator"
default:
NO
NO
static: referencedto:
global.fieldPermissions.freeTime:readable
persistent:
YES
local.personVehicle.findVisitor
default: persistent:
NO
true
Language
name:
NO
NO YES
false
Language
NO
NO NO
true
global.fieldPermissions.language:name
NO YES
local.personVehicle.unblockToken
YES
false
static:
name: default: static:
true
name:
local.personVehicle.assignToken:setBadgeNumber
persistent:
false
default:
name:
referencedto:
persistent:
bulkEdit.bulkContractor1 bulkEdit.bulkContractor2 bulkEdit.bulkContractor3
global.temporary
static:
NO
NO
persistent:
name: default: persistent: referencedto:
NO
NO
referencedto:
NO
NO
static:
NO
NO
static:
static:
NO
NO
persistent:
referencedto:
name:
YES
referencedto:
referencedto:
persistent:
NO
static:
administrator
administrator
false
NO
static:
local.visit.findVisit
default: persistent: referencedto:
local.loginProcedure.username
NO
NO
NO
local.personVehicle.replace:ID NO
NO
NO
name:
NO YES
name:
bulkEdit.bulkContractor1 bulkEdit.bulkContractor2 bulkEdit.bulkContractor3
false
local.dashBoard.replace:ID
local.personVehicle.bulkListEmployee bulkEdit.bulkEmployee1 bulkEdit.bulkEmployee2 bulkEdit.bulkEmployee3
static:
default: persistent:
NO
NO
persistent: referencedto:
"userAdministrator"
name:
referencedto:
local.personVehicle.currentRequest
default:
administrator
persistent:
NO
NO YES
default:
YES
name: default:
NO
static: referencedto:
persistent:
static:
NO YES
default: persistent:
NO
referencedto:
NO
static:
default:
"userAdministrator"
default:
persistent: referencedto:
NO
static:
false
static:
NO
global.userAdministrator
persistent: referencedto:
"userAdministrator"
local.createEmployee.addCarrierAuthorizations
persistent: referencedto:
global.environmentPrepared
default:
NO
global.fieldPermissions.freeDate
name:
persistent:
NO
default:
global.fieldPermissions.freeString
persistent:
NO
referencedto:
NO
static:
default:
default:
NO
false
static:
true
YES
referencedto:
local.createEmployee.changeContractor:setId
persistent: referencedto:
name: global.user "userAdministrator"
static:
default: static:
NO
static:
default:
name: default: persistent:
persistent: referencedto:
false
local.personVehicle.replaceToken
persistent:
default:
NO
NO
bulkEdit.bulkEmployee1 bulkEdit.bulkEmployee2 bulkEdit.bulkEmployee3
persistent: name:
static:
NO
NO
static:
name:
name:
true
local.personVehicle.badgeEditorOpenSuccess
persistent:
NO
global.userVisitorsOnly
default: persistent:
NO
global.fieldPermissions.freeBoolean:mandatory
false name:
NO
name:
NO
name:
NO
static:
default:
referencedto:
default:
NO
"userAdministrator"
name:
true
local.personVehicle.carrier:created
YES
true
false
name:
NO
referencedto:
local.main.currentField
default:
persistent:
name:
NO YES
NO
static:
referencedto:
NO YES
global.bulkEdit.bulkContractor2:blocked
default:
default:
NO true
static:
NO
persistent:
NO
static: referencedto:
local.createEmployee.changeVisitor:setId
default:
persistent:
NO
false
NO
static: referencedto:
false name:
default:
NO
static:
NO
NO
NO
referencedto:
global.fieldPermissions.freeDateTime
persistent: local.createEmployee.mode
default:
NO
static:
persistent:
NO
default: name:
persistent:
NO
static: referencedto:
global.bulkEdit.bulkMixed2:created
NO freeString
default:
referencedto:
persistent: NO
default:
persistent:
global.fieldPermissions.department:value
default: NO
static:
YES
NO
static:
local.personVehicle.blockToken:setReason
persistent: referencedto:
freeString
persistent:
persistent: referencedto:
NO
default:
global.fieldPermissions.freeString:name
default:
default:
NO
testString
false
NO
true
name:
local.mainButtons.widgets.textEvents
static:
false
name: name: name: default: persistent:
persistent:
static:
local.quickLaunch.host:lastName
name: default:
persistent: local.personVehicle.findCar
default:
global.userBosse:visit
default: persistent: referencedto:
name:
referencedto:
local.personVehicle.carrier:lastName
default: name:
default:
name:
persistent:
name:
default:
default:
persistent:
NO
false
local.personVehicle.findEmployee
default:
NO
local.createEmployee.addVisitor:getId
default:
default:
name:
NO YES
"userAdministrator" "userAdministrator"
local.createEmployee.findDepartment
name:
name:
static: referencedto:
NO
static: referencedto:
global.userNoFunctions
default:
NO YES
global.fieldPermissions.freeBoolean
default:
static:
persistent: NO
static: referencedto:
persistent: name:
NO
referencedto:
global.userBadgeOnly
default:
global.fieldPermissions.department
default: persistent:
name:
local.quickLaunch.replace:ID
default:
name:
local.dashBoard.badge:ID
persistent:
NO
static:
NO
referencedto:
NO
default:
persistent:
NO
persistent:
NO
static:
NO
static:
NO
referencedto:
NO
referencedto:
NO
Figuur 4.2: Weergave van de variabelen na statische analyse door NTA2
Pagina 18