From 2a84ee91e979f1916f5c1871fe07591a71f98b61 Mon Sep 17 00:00:00 2001 From: Philip Makedonski <makedonski@informatik.uni-goettingen.de> Date: Fri, 22 Dec 2023 14:00:39 +0100 Subject: [PATCH] + mwt plugtest examples (WIP) --- mwt-examples/.classpath | 7 + mwt-examples/.project | 25 + .../.settings/org.eclipse.jdt.core.prefs | 10 + mwt-examples/META-INF/MANIFEST.MF | 9 + mwt-examples/README.md | 7 + mwt-examples/build.properties | 4 + mwt-examples/src/tdl/Config.tdltx | 72 +++ mwt-examples/src/tdl/Data.tdltx | 7 + mwt-examples/src/tdl/Descriptions.tdltx | 320 ++++++++++ mwt-examples/src/tdl/Descriptions.tdltx.docx | Bin 0 -> 14363 bytes mwt-examples/src/tdl/Descriptions.tdltx.tdl | 587 ++++++++++++++++++ mwt-examples/src/tdl/HTTP.tdltx | 126 ++++ mwt-examples/src/tdl/Objectives.tdltx | 64 ++ mwt-examples/src/tdl/Standard.tdltx | 56 ++ mwt-examples/src/tdl/step2body.json | 12 + .../src/tdl/step2body.json-generated.tdltx | 43 ++ mwt-examples/src/tdl/step3body-translate.json | 85 +++ mwt-examples/src/tdl/step3body.json | 85 +++ .../src/tdl/step3body.json-generated.tdltx | 132 ++++ 19 files changed, 1651 insertions(+) create mode 100644 mwt-examples/.classpath create mode 100644 mwt-examples/.project create mode 100644 mwt-examples/.settings/org.eclipse.jdt.core.prefs create mode 100644 mwt-examples/META-INF/MANIFEST.MF create mode 100644 mwt-examples/README.md create mode 100644 mwt-examples/build.properties create mode 100644 mwt-examples/src/tdl/Config.tdltx create mode 100644 mwt-examples/src/tdl/Data.tdltx create mode 100644 mwt-examples/src/tdl/Descriptions.tdltx create mode 100644 mwt-examples/src/tdl/Descriptions.tdltx.docx create mode 100644 mwt-examples/src/tdl/Descriptions.tdltx.tdl create mode 100644 mwt-examples/src/tdl/HTTP.tdltx create mode 100644 mwt-examples/src/tdl/Objectives.tdltx create mode 100644 mwt-examples/src/tdl/Standard.tdltx create mode 100644 mwt-examples/src/tdl/step2body.json create mode 100644 mwt-examples/src/tdl/step2body.json-generated.tdltx create mode 100644 mwt-examples/src/tdl/step3body-translate.json create mode 100644 mwt-examples/src/tdl/step3body.json create mode 100644 mwt-examples/src/tdl/step3body.json-generated.tdltx diff --git a/mwt-examples/.classpath b/mwt-examples/.classpath new file mode 100644 index 0000000..1a82131 --- /dev/null +++ b/mwt-examples/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/mwt-examples/.project b/mwt-examples/.project new file mode 100644 index 0000000..f9e2a54 --- /dev/null +++ b/mwt-examples/.project @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>mwt-plugtests</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.xtext.ui.shared.xtextBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.xtext.ui.shared.xtextNature</nature> + <nature>org.etsi.mts.tdl.nature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + </natures> +</projectDescription> diff --git a/mwt-examples/.settings/org.eclipse.jdt.core.prefs b/mwt-examples/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..d4540a5 --- /dev/null +++ b/mwt-examples/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,10 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/mwt-examples/META-INF/MANIFEST.MF b/mwt-examples/META-INF/MANIFEST.MF new file mode 100644 index 0000000..ac6f2b6 --- /dev/null +++ b/mwt-examples/META-INF/MANIFEST.MF @@ -0,0 +1,9 @@ +Manifest-Version: 1.0 +Automatic-Module-Name: postman-mwt-plugtests +Bundle-ManifestVersion: 2 +Bundle-Name: postman-mwt-plugtests +Bundle-Vendor: My Company +Bundle-Version: 1.0.0.qualifier +Bundle-SymbolicName: mwt-plugtests;singleton:=true +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-17 diff --git a/mwt-examples/README.md b/mwt-examples/README.md new file mode 100644 index 0000000..d6e8ccd --- /dev/null +++ b/mwt-examples/README.md @@ -0,0 +1,7 @@ +# mWT Plugtest Examples + +This project contains prototypical exploration of converting examples from the mWT plugtests to TDL. The goal is to explore suitability and open questions and provide a guideline for future plugtests and similar definitions. + +The examples are derived from the [ETSI Plugtests Test Plan V1.0 (2020-11)](https://portal.etsi.org/Portals/0/TBpages/CTI/Docs/mWT_Plugtests2-3_TestPlan_v1_0.pdf) and the [Postman implementations](https://forge.etsi.org/rep/sdn/mwt/plugtests-3). + +TODO: Observations and notes to be added. \ No newline at end of file diff --git a/mwt-examples/build.properties b/mwt-examples/build.properties new file mode 100644 index 0000000..cc91072 --- /dev/null +++ b/mwt-examples/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/mwt-examples/src/tdl/Config.tdltx b/mwt-examples/src/tdl/Config.tdltx new file mode 100644 index 0000000..370f692 --- /dev/null +++ b/mwt-examples/src/tdl/Config.tdltx @@ -0,0 +1,72 @@ +/* + * This is an example package + */ +Package Config { + Import all from Standard + Import all from HTTP + Import all from HTTP.MessageBased + Import all from generated_from_step3body_json + Import all from generated_from_step2body_json + //example type + Type float + //define additional elements here + + Type message + + Message Gate MPI accepts message, JSON_step2body_json, JSON, Response, Request, String + + Component DomainController { + gate MPI mpi + } + + Component Postman { + variable Response response + variable Integer i + timer t + gate MPI mpi + } + + Component NE { + gate MPI mpi //? + } + + Component OpticalPatchPanel { + gate MPI mpi //? + } + + Component TrafficGeneratorAndAnalyser { + gate MPI mpi //? + } + + Configuration GenericTestArchitecture { + Postman pm as Tester, + DomainController M1 as SUT, + DomainController M2 as SUT, + //... + connect M1::mpi to pm::mpi, //TODO: this should be fine + connect M2::mpi to pm::mpi + //... + } + + Configuration TestLanArchitecture { + Postman pm as Tester, + DomainController X as SUT, + //... + connect X::mpi to pm::mpi + //... + } + + //Lots and lots of configurations that need to be + + //Or are some of those configuraitons that are setup to be tested virtually? + Configuration TREE_CFG { + //Postman pm as Tester, + TrafficGeneratorAndAnalyser traffic as Tester, + DomainController X as SUT, + //,,, + connect X::mpi to traffic::mpi + //... + } + + +} diff --git a/mwt-examples/src/tdl/Data.tdltx b/mwt-examples/src/tdl/Data.tdltx new file mode 100644 index 0000000..215c0ee --- /dev/null +++ b/mwt-examples/src/tdl/Data.tdltx @@ -0,0 +1,7 @@ +/* + * This is an example model + */ +Package Data { + + +} diff --git a/mwt-examples/src/tdl/Descriptions.tdltx b/mwt-examples/src/tdl/Descriptions.tdltx new file mode 100644 index 0000000..d162bbe --- /dev/null +++ b/mwt-examples/src/tdl/Descriptions.tdltx @@ -0,0 +1,320 @@ +Package Descriptions { + Import all from Standard + Import all from Objectives + Import all from Config + Import all from generated_from_step3body_json + Import all from generated_from_step2body_json + Import all from HTTP.MessageBased + + Annotation Failure + Type ^PICS extends Boolean + ^PICS MW_8040 + ^PICS MW_8345 + + Boolean TD_SSP_01_Completed + + String modules_state_uri + Use "pm.settings.json" as SETTINGS + Map modules_state_uri + to "{{TD_SDN_RESTCONF_PATH}}/data/ietf-yang-library:modules-state" + in SETTINGS + as modules_state_uri_MAPPING + + //TODO:to be imported from protocol definition + Structure JSON_modules_state extends Body ( + String modules_state, + Modules modules + ) + + JSON_modules_state JSON_instance_modules_state () + + Collection Modules of Module + Structure Module ( + String name, + String revision, + String namespace + ) + + + // ... + + //TODO: clean up, align, document, and share + Test Description DomainControllerInitialisation uses TestLanArchitecture + Test Description DomainControllersInitialisation uses TestLanArchitecture + Test Description DevicesUpgrade uses TestLanArchitecture + Test Description BasicConfigurationsSetup uses TestLanArchitecture + Test Description L2DataServicesCreation uses TestLanArchitecture + Test Description ResetDomainControllers uses TestLanArchitecture + Test Description ResetMicrowaveUnits uses TestLanArchitecture + + Objective ResponseContainsAllYanModules { + Description: "The response body of the request should contain a list of all YANG modules" + References: "Postman implementation" + } + + + Test Purpose Description TPD_MDD_01 { + Objective: TD_MDD_01 + Configuration: TestLanArchitecture //TREE_CFG? + PICS: (MW_8040 or MW_8345) //etc. + Initial conditions + with { + //initial textual + perform action: "Postman has been correctly initialized earlier, by executing + TD_POSTMAN_INIT" + perform action: "All the Domain Controller instances up and running normally" + perform action: "All the devices are upgraded to correct versions" + perform action: "All basic configurations are completed (e.g., NE_id, OSPF, PCEP, etc.)" + //then gradually formalised, e.g. + execute DomainControllersInitialisation + execute DevicesUpgrade + execute BasicConfigurationsSetup + //!DONE: check constraints above -> fixed + //... + } + Expected behaviour + ensure that { + when { + //initial textual + perform action: "Send GET request via Postman to all domain controllers by + executing Collection TD_MDD_01" + //refine to first structure + //TODO: what happens to all the parentheses?!?! -> make filter optional (or remove?) + pm::mpi sends rGET() to X::mpi + //refine to specific uri inline + pm::mpi sends rGET( + uri = "{{TD_SDN_RESTCONF_PATH}}/data/ietf-yang-library:modules-state" + ) to X::mpi + //...or define elsewhere + pm::mpi sends rGET( + uri = modules_state_uri + ) to X::mpi + } + then { + //initial textual + perform action: "Check the response body of each request and confirm if all the + Restconf servers are serviceable." + perform action: "The response body of the request should contain a list of all + YANG modules and submodules used by the Restconf server along with + information about name and revision for each module." + perform action: "The response body of each query should contain the specified YANG + module along with its name and revision." + + //refinements + // Test 1: Check the response body of the above request and confirm if the Restconf + // server is serviceable. + pm::mpi receives OK() from X::mpi + + + // Step 2: The response body of the request should contain a list of all YANG modules + //and submodules used by the Restconf server along with information about name and revision + //for each module. + + //--- + //asserts can be used but probably simpler to use a specification of the expected data + //optionally: explicit objective that can be checked + Objective: ResponseContainsAllYanModules + pm::mpi receives OK( + body = JSON_instance_modules_state( + modules_state = ?, + modules_state = ?, + //TODO: do we need a pattern ? / * for collections? Otherwise we need a loop instead + //TODO: as a side note, is checking for the presence of a property + // equivalent to that property having any value? + modules[*] = (name = ?, revision = ?, namespace = ?) + //... + )) from X::mpi + + //asserts can provide fine granular diagnostics though, for individual problems + response = pm::mpi receives OK() from X::mpi + //optionally: explicit objective that can be checked + Objective: ResponseContainsAllYanModules + //optionally: annotations can be used for inline information + @Failure: "The response body of the request should contain a list of all YANG modules" + //TODO: property access for subclasses? + //TODO: do we have matching expressions in assertions as well + //TODO: do we have checking of types + assert ( pm::response.body == JSON_instance_modules_state( + modules_state = ?, + //TODO: do we need a pattern ? / * for collections? Otherwise we need a loop instead + //TODO: as a side note, is checking for the presence of a property + // equivalent to that property having any value? + modules[*] = (name = ?, revision = ?, namespace = ?) + // + )) + on pm //may be skipped at first + with { + timeLabel=now + } + + //alternatively with a loop + //TODO: do we need counters? integrated in loops? e.g. with state to address collections? + pm::i = 0 + repeat 5 times on pm + //[MW_8040] + { + //DONE: fixed constraint with bounded loop behaviour, still not quite there + assert ( pm::response.body == JSON_instance_modules_state( + modules_state = ?, + //TODO: as a side note, is checking for the presence of a property + // equivalent to that property having any value? + modules[pm::i] = (name = ?, revision = ?, namespace = ?) + // + )) + on pm //may be skipped at first + //DONE: handle undefined return types -> a bit of a hack, assuming they are the same + pm::i = ( pm::i + 1 ) + } + } + } + } + + + + + Test Purpose Description TPD_MSP_01 { + Objective: TD_MSP_01 + Configuration: TestLanArchitecture //TREE_CFG? + PICS: (MW_8040 or MW_8345) //etc. + Initial conditions + with { + //initial textual + perform action: "Postman has been correctly initialized earlier, by executing TD_POSTMAN_INIT" + perform action: "The Domain Controller instance is up and running normally" + perform action: "All the devices are upgraded to correct versions" + perform action: "All basic configurations are completed (e.g., NE_id, OSPF, PCEP, etc.)" + perform action: "All Restconf servers are serviceable." + perform action: "If TD_SSP_01 has been run before TD_ MSP_01, all Domain Controllers and + microwave units should be reset to the state they were before executing + TD_SSP_01" + //then gradually formalised, e.g. + execute DomainControllerInitialisation + execute DomainControllerInitialisation + execute DevicesUpgrade + execute BasicConfigurationsSetup + if [TD_SSP_01_Completed] { + execute ResetDomainControllers + execute ResetMicrowaveUnits + } + //!TODO: check constraints above + //... + } + Expected behaviour + ensure that { + when { + //initial textual + perform action: "Send POST request via Postman to all domain controllers + by executing Collection TD_ SSP_01" +// //refine to first structure +// pm::mpi sends rPOST() to X::mpi +// //refine to specific body (or define inline) +// pm::mpi sends rPOST(body = JSON_instance) to X::mpi +// +// //provide additional parameter overrides +// pm::mpi sends rPOST( +// body = JSON_instance ( +// services[0].adminStatus = "up", +// //.. +// //TODO: check constraints +// services[0].ports[1].accessNodeId = node1 +// //.. +// ) +// ) +// to X::mpi //.... + } + then { + //initial textual + perform action: "Check the TGA if the data start flowing properly." +// pm::mpi receives OK() from X::mpi +// pm::mpi receives OK(body = JSON_instance) from X::mpi +// pm::mpi receives OK( +// body = JSON_instance( +// //.. +// services[2] = omit, +// //... +// services[3].ports[1] = omit +// ) +// ) +// from X::mpi +// //first response definition, then refined, also with overrides +// //!TODO: Why are comments before receive message not OK? +// //... refine further + } + } + } + + + + Test Purpose Description TPD_MSP_04 { + Objective: TD_MSP_04 + Configuration: TestLanArchitecture //TREE_CFG? + PICS: (MW_8040 or MW_8345) //etc. + Initial conditions + with { + //initial textual + perform action: "Postman has been correctly initialized earlier, by executing TD_POSTMAN_INIT" + perform action: "All the Domain Controller instances are up and running normally" + perform action: "All the devices are upgraded to correct versions" + perform action: "All basic configurations are completed (e.g., NE_id, OSPF, PCEP, etc.)" + perform action: "All Restconf servers are serviceable." + perform action: "All L2 data services are successfully created." + //then gradually formalised, e.g. + execute DomainControllersInitialisation + execute DevicesUpgrade + execute BasicConfigurationsSetup + execute L2DataServicesCreation + //!TODO: check constraints above + //... + } + Expected behaviour + ensure that { + when { + //initial textual + perform action: "Send GET request via Postman to + all domain controllers by executing + Collection TD_MSP_04" + //refine to first structure + pm::mpi sends rGET() to X::mpi + //refine to specific body (or define inline) + pm::mpi sends rGET(body = JSON_instance) to X::mpi + + //provide additional parameter overrides + pm::mpi sends rGET( + body = JSON_instance ( + services[0].adminStatus = "up" {JSON_String}, + //.. + //DONE: check constraints + services[0].ports[1].accessNodeId = node1 + //.. + ) + ) + to X::mpi //.... + } + then { + //initial textual + perform action: "The response body should no longer contain + information about the L2 service deleted in TD_MSP_03" + //!DONE: Why are comments before receive message not OK? -> fixed + //basic response definition + pm::mpi receives OK() from X::mpi + //refined with reference to body definition + pm::mpi receives OK(body = JSON_instance) from X::mpi + //refined with inline overrides + pm::mpi receives OK( + body = JSON_instance( + //.. + //TODO: does an optional collection member imply entire collection is ommitted? + // or also individual items? + //TODO: does special value use conform to everything? + services[2] = omit, + //... + services[3].ports[1] = omit + ) + ) + from X::mpi + //... refine further + } + } + } + +} \ No newline at end of file diff --git a/mwt-examples/src/tdl/Descriptions.tdltx.docx b/mwt-examples/src/tdl/Descriptions.tdltx.docx new file mode 100644 index 0000000000000000000000000000000000000000..8533f27daa0bd20a05d72edfbbc5acee0e85198d GIT binary patch literal 14363 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 Q0QU8I`?@*c%zw2118+*o%K!iX literal 0 HcmV?d00001 diff --git a/mwt-examples/src/tdl/Descriptions.tdltx.tdl b/mwt-examples/src/tdl/Descriptions.tdltx.tdl new file mode 100644 index 0000000..245c957 --- /dev/null +++ b/mwt-examples/src/tdl/Descriptions.tdltx.tdl @@ -0,0 +1,587 @@ +<?xml version="1.0" encoding="ASCII"?> +<tdl:Package xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tdl="http://www.etsi.org/spec/TDL/1.4.1" name="Descriptions"> + <packagedElement xsi:type="tdl:AnnotationType" name="Failure"/> + <packagedElement xsi:type="tdl:SimpleDataType" name="PICS"> + <extension> + <extending xsi:type="tdl:SimpleDataType" href="Standard.tdltx#//@packagedElement.7"/> + </extension> + </packagedElement> + <packagedElement xsi:type="tdl:SimpleDataInstance" name="MW_8040" dataType="//@packagedElement.1"/> + <packagedElement xsi:type="tdl:SimpleDataInstance" name="MW_8345" dataType="//@packagedElement.1"/> + <packagedElement xsi:type="tdl:SimpleDataInstance" name="TD_SSP_01_Completed"> + <dataType xsi:type="tdl:SimpleDataType" href="Standard.tdltx#//@packagedElement.7"/> + </packagedElement> + <packagedElement xsi:type="tdl:SimpleDataInstance" name="modules_state_uri"> + <dataType xsi:type="tdl:SimpleDataType" href="Standard.tdltx#//@packagedElement.9"/> + </packagedElement> + <packagedElement xsi:type="tdl:DataResourceMapping" name="SETTINGS" resourceURI="pm.settings.json"/> + <packagedElement xsi:type="tdl:DataElementMapping" name="modules_state_uri_MAPPING" mappableDataElement="//@packagedElement.5" elementURI="{{TD_SDN_RESTCONF_PATH}}/data/ietf-yang-library:modules-state" dataResourceMapping="//@packagedElement.6"/> + <packagedElement xsi:type="tdl:StructuredDataType" name="JSON_modules_state"> + <extension> + <extending xsi:type="tdl:StructuredDataType" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.30"/> + </extension> + <member name="modules_state"> + <dataType xsi:type="tdl:SimpleDataType" href="Standard.tdltx#//@packagedElement.9"/> + </member> + <member name="modules" dataType="//@packagedElement.10"/> + </packagedElement> + <packagedElement xsi:type="tdl:StructuredDataInstance" name="JSON_instance_modules_state" dataType="//@packagedElement.8"/> + <packagedElement xsi:type="tdl:CollectionDataType" name="Modules" itemType="//@packagedElement.11"/> + <packagedElement xsi:type="tdl:StructuredDataType" name="Module"> + <member name="name"> + <dataType xsi:type="tdl:SimpleDataType" href="Standard.tdltx#//@packagedElement.9"/> + </member> + <member name="revision"> + <dataType xsi:type="tdl:SimpleDataType" href="Standard.tdltx#//@packagedElement.9"/> + </member> + <member name="namespace"> + <dataType xsi:type="tdl:SimpleDataType" href="Standard.tdltx#//@packagedElement.9"/> + </member> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="DomainControllerInitialisation"> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="DomainControllersInitialisation"> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="DevicesUpgrade"> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="BasicConfigurationsSetup"> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="L2DataServicesCreation"> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="ResetDomainControllers"> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="ResetMicrowaveUnits"> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + </packagedElement> + <packagedElement xsi:type="tdl:TestObjective" name="ResponseContainsAllYanModules" description="The response body of the request should contain a list of all YANG modules"> + <objectiveURI>Postman implementation</objectiveURI> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="TPD_MDD_01"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.22"/> + </annotation> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + <behaviourDescription> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <block> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.19"/> + </annotation> + <block> + <behaviour xsi:type="tdl:InlineAction" body="Postman has been correctly initialized earlier, by executing 
 TD_POSTMAN_INIT"/> + <behaviour xsi:type="tdl:InlineAction" body="All the Domain Controller instances up and running normally"/> + <behaviour xsi:type="tdl:InlineAction" body="All the devices are upgraded to correct versions"/> + <behaviour xsi:type="tdl:InlineAction" body="All basic configurations are completed (e.g., NE_id, OSPF, PCEP, etc.)"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.13"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.14"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.15"/> + </block> + </behaviour> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.20"/> + </annotation> + <block> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.23"/> + </annotation> + <block> + <behaviour xsi:type="tdl:InlineAction" body="Send GET request via Postman to all domain controllers by 
 executing Collection TD_MDD_01"/> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.2"/> + </argument> + </behaviour> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <argument> + <dataUse xsi:type="tdl:LiteralValueUse" value="{{TD_SDN_RESTCONF_PATH}}/data/ietf-yang-library:modules-state"/> + <parameter xsi:type="tdl:Member" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.1/@member.0"/> + </argument> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.2"/> + </argument> + </behaviour> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <argument> + <dataUse xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.5"/> + <parameter xsi:type="tdl:Member" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.1/@member.0"/> + </argument> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.2"/> + </argument> + </behaviour> + </block> + </behaviour> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.24"/> + </annotation> + <block> + <behaviour xsi:type="tdl:InlineAction" body="Check the response body of each request and confirm if all the 
 Restconf servers are serviceable."/> + <behaviour xsi:type="tdl:InlineAction" body="The response body of the request should contain a list of all 
 YANG modules and submodules used by the Restconf server along with 
 information about name and revision for each module."/> + <behaviour xsi:type="tdl:InlineAction" body="The response body of each query should contain the specified YANG 
 module along with its name and revision."/> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.15"/> + </argument> + </behaviour> + <behaviour xsi:type="tdl:Message" testObjective="//@packagedElement.19"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <argument> + <dataUse xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.9"> + <argument parameter="//@packagedElement.8/@member.0"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.8/@member.0"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.8/@member.1"> + <dataUse xsi:type="tdl:DataElementUse"> + <argument parameter="//@packagedElement.11/@member.0"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.11/@member.1"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.11/@member.2"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + </dataUse> + <reduction> + <collectionIndex xsi:type="tdl:AnyValueOrOmit" name="*"/> + </reduction> + </argument> + </dataUse> + <parameter xsi:type="tdl:Member" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.7/@member.3"/> + </argument> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.15"/> + </argument> + </behaviour> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + <valueAssignment> + <variable href="Config.tdltx#//@packagedElement.4/@variable.0"/> + </valueAssignment> + </target> + <argument xsi:type="tdl:DataElementUse"> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.15"/> + </argument> + </behaviour> + <behaviour xsi:type="tdl:Assertion" testObjective="//@packagedElement.19"> + <annotation value="The response body of the request should contain a list of all YANG modules" key="//@packagedElement.0"/> + <timeLabel name="timeLabel"/> + <componentInstance href="Config.tdltx#//@packagedElement.9/@componentInstance.0"/> + <condition xsi:type="tdl:PredefinedFunctionCall"> + <function href="Standard.tdltx#//@packagedElement.25"/> + <actualParameters xsi:type="tdl:VariableUse"> + <reduction> + <member href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.7/@member.3"/> + </reduction> + <componentInstance href="Config.tdltx#//@packagedElement.9/@componentInstance.0"/> + <variable href="Config.tdltx#//@packagedElement.4/@variable.0"/> + </actualParameters> + <actualParameters xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.9"> + <argument parameter="//@packagedElement.8/@member.0"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.8/@member.1"> + <dataUse xsi:type="tdl:DataElementUse"> + <argument parameter="//@packagedElement.11/@member.0"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.11/@member.1"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.11/@member.2"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + </dataUse> + <reduction> + <collectionIndex xsi:type="tdl:AnyValueOrOmit" name="*"/> + </reduction> + </argument> + </actualParameters> + </condition> + </behaviour> + <behaviour xsi:type="tdl:Assignment"> + <variable> + <componentInstance href="Config.tdltx#//@packagedElement.9/@componentInstance.0"/> + <variable href="Config.tdltx#//@packagedElement.4/@variable.1"/> + </variable> + <expression xsi:type="tdl:LiteralValueUse" intValue="0"/> + </behaviour> + <behaviour xsi:type="tdl:BoundedLoopBehaviour"> + <block> + <behaviour xsi:type="tdl:Assertion"> + <componentInstance href="Config.tdltx#//@packagedElement.9/@componentInstance.0"/> + <condition xsi:type="tdl:PredefinedFunctionCall"> + <function href="Standard.tdltx#//@packagedElement.25"/> + <actualParameters xsi:type="tdl:VariableUse"> + <reduction> + <member href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.7/@member.3"/> + </reduction> + <componentInstance href="Config.tdltx#//@packagedElement.9/@componentInstance.0"/> + <variable href="Config.tdltx#//@packagedElement.4/@variable.0"/> + </actualParameters> + <actualParameters xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.9"> + <argument parameter="//@packagedElement.8/@member.0"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.8/@member.1"> + <dataUse xsi:type="tdl:DataElementUse"> + <argument parameter="//@packagedElement.11/@member.0"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.11/@member.1"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + <argument parameter="//@packagedElement.11/@member.2"> + <dataUse xsi:type="tdl:AnyValue" name="?"/> + </argument> + </dataUse> + <reduction> + <collectionIndex xsi:type="tdl:VariableUse"> + <componentInstance href="Config.tdltx#//@packagedElement.9/@componentInstance.0"/> + <variable href="Config.tdltx#//@packagedElement.4/@variable.1"/> + </collectionIndex> + </reduction> + </argument> + </actualParameters> + </condition> + </behaviour> + <behaviour xsi:type="tdl:Assignment"> + <variable> + <componentInstance href="Config.tdltx#//@packagedElement.9/@componentInstance.0"/> + <variable href="Config.tdltx#//@packagedElement.4/@variable.1"/> + </variable> + <expression xsi:type="tdl:PredefinedFunctionCall"> + <function href="Standard.tdltx#//@packagedElement.35"/> + <actualParameters xsi:type="tdl:VariableUse"> + <componentInstance href="Config.tdltx#//@packagedElement.9/@componentInstance.0"/> + <variable href="Config.tdltx#//@packagedElement.4/@variable.1"/> + </actualParameters> + <actualParameters xsi:type="tdl:LiteralValueUse" intValue="1"/> + </expression> + </behaviour> + </block> + <numIteration> + <expression xsi:type="tdl:LiteralValueUse" intValue="5"/> + <componentInstance href="Config.tdltx#//@packagedElement.9/@componentInstance.0"/> + </numIteration> + </behaviour> + </block> + </behaviour> + </block> + </behaviour> + <guard> + <expression xsi:type="tdl:PredefinedFunctionCall"> + <function href="Standard.tdltx#//@packagedElement.28"/> + <actualParameters xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.2"/> + <actualParameters xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.3"/> + </expression> + </guard> + </block> + </behaviour> + </behaviourDescription> + <testObjective href="Objectives.tdltx#//@packagedElement.0"/> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="TPD_MSP_01"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.22"/> + </annotation> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + <behaviourDescription> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <block> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.19"/> + </annotation> + <block> + <behaviour xsi:type="tdl:InlineAction" body="Postman has been correctly initialized earlier, by executing TD_POSTMAN_INIT"/> + <behaviour xsi:type="tdl:InlineAction" body="The Domain Controller instance is up and running normally"/> + <behaviour xsi:type="tdl:InlineAction" body="All the devices are upgraded to correct versions"/> + <behaviour xsi:type="tdl:InlineAction" body="All basic configurations are completed (e.g., NE_id, OSPF, PCEP, etc.)"/> + <behaviour xsi:type="tdl:InlineAction" body="All Restconf servers are serviceable."/> + <behaviour xsi:type="tdl:InlineAction" body="If TD_SSP_01 has been run before TD_ MSP_01, all Domain Controllers and 
 microwave units should be reset to the state they were before executing 
 TD_SSP_01"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.12"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.12"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.14"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.15"/> + <behaviour xsi:type="tdl:ConditionalBehaviour"> + <block> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.17"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.18"/> + <guard> + <expression xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.4"/> + </guard> + </block> + </behaviour> + </block> + </behaviour> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.20"/> + </annotation> + <block> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.23"/> + </annotation> + <block> + <behaviour xsi:type="tdl:InlineAction" body="Send POST request via Postman to all domain controllers 
 by executing Collection TD_ SSP_01"/> + </block> + </behaviour> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.24"/> + </annotation> + <block> + <behaviour xsi:type="tdl:InlineAction" body="Check the TGA if the data start flowing properly."/> + </block> + </behaviour> + </block> + </behaviour> + <guard> + <expression xsi:type="tdl:PredefinedFunctionCall"> + <function href="Standard.tdltx#//@packagedElement.28"/> + <actualParameters xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.2"/> + <actualParameters xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.3"/> + </expression> + </guard> + </block> + </behaviour> + </behaviourDescription> + <testObjective href="Objectives.tdltx#//@packagedElement.3"/> + </packagedElement> + <packagedElement xsi:type="tdl:TestDescription" name="TPD_MSP_04"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.22"/> + </annotation> + <testConfiguration href="Config.tdltx#//@packagedElement.9"/> + <behaviourDescription> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <block> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.19"/> + </annotation> + <block> + <behaviour xsi:type="tdl:InlineAction" body="Postman has been correctly initialized earlier, by executing TD_POSTMAN_INIT"/> + <behaviour xsi:type="tdl:InlineAction" body="All the Domain Controller instances are up and running normally"/> + <behaviour xsi:type="tdl:InlineAction" body="All the devices are upgraded to correct versions"/> + <behaviour xsi:type="tdl:InlineAction" body="All basic configurations are completed (e.g., NE_id, OSPF, PCEP, etc.)"/> + <behaviour xsi:type="tdl:InlineAction" body="All Restconf servers are serviceable."/> + <behaviour xsi:type="tdl:InlineAction" body="All L2 data services are successfully created."/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.13"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.14"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.15"/> + <behaviour xsi:type="tdl:TestDescriptionReference" testDescription="//@packagedElement.16"/> + </block> + </behaviour> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.20"/> + </annotation> + <block> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.23"/> + </annotation> + <block> + <behaviour xsi:type="tdl:InlineAction" body="Send GET request via Postman to 
 all domain controllers by executing 
 Collection TD_MSP_04"/> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.2"/> + </argument> + </behaviour> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <argument> + <dataUse xsi:type="tdl:DataElementUse"> + <dataElement xsi:type="tdl:StructuredDataInstance" href="step3body.json-generated.tdltx#//@packagedElement.18"/> + </dataUse> + <parameter xsi:type="tdl:Member" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.1/@member.4"/> + </argument> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.2"/> + </argument> + </behaviour> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <argument> + <dataUse xsi:type="tdl:DataElementUse"> + <argument> + <dataUse xsi:type="tdl:LiteralValueUse" value="up"/> + <parameter xsi:type="tdl:Member" href="step3body.json-generated.tdltx#//@packagedElement.4/@member.0"/> + <reduction> + <collectionIndex xsi:type="tdl:LiteralValueUse" intValue="0"/> + </reduction> + <reduction> + <member href="step3body.json-generated.tdltx#//@packagedElement.6/@member.1"/> + </reduction> + </argument> + <argument> + <dataUse xsi:type="tdl:DataElementUse"> + <dataElement xsi:type="tdl:SimpleDataInstance" href="step3body.json-generated.tdltx#//@packagedElement.11"/> + </dataUse> + <parameter xsi:type="tdl:Member" href="step3body.json-generated.tdltx#//@packagedElement.4/@member.0"/> + <reduction> + <collectionIndex xsi:type="tdl:LiteralValueUse" intValue="0"/> + </reduction> + <reduction> + <member href="step3body.json-generated.tdltx#//@packagedElement.6/@member.2"/> + <collectionIndex xsi:type="tdl:LiteralValueUse" intValue="1"/> + </reduction> + <reduction> + <member href="step3body.json-generated.tdltx#//@packagedElement.17/@member.0"/> + </reduction> + </argument> + <dataElement xsi:type="tdl:StructuredDataInstance" href="step3body.json-generated.tdltx#//@packagedElement.18"/> + </dataUse> + <parameter xsi:type="tdl:Member" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.1/@member.4"/> + </argument> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.2"/> + </argument> + </behaviour> + </block> + </behaviour> + <behaviour xsi:type="tdl:CompoundBehaviour"> + <annotation> + <key href="Standard.tdltx#//@packagedElement.24"/> + </annotation> + <block> + <behaviour xsi:type="tdl:InlineAction" body="The response body should no longer contain 
 information about the L2 service deleted in TD_MSP_03"/> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.15"/> + </argument> + </behaviour> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <argument> + <dataUse xsi:type="tdl:DataElementUse"> + <dataElement xsi:type="tdl:StructuredDataInstance" href="step3body.json-generated.tdltx#//@packagedElement.18"/> + </dataUse> + <parameter xsi:type="tdl:Member" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.7/@member.3"/> + </argument> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.15"/> + </argument> + </behaviour> + <behaviour xsi:type="tdl:Message"> + <sourceGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.0"/> + <target> + <targetGate href="Config.tdltx#//@packagedElement.9/@connection.0/@endPoint.1"/> + </target> + <argument xsi:type="tdl:DataElementUse"> + <argument> + <dataUse xsi:type="tdl:DataElementUse"> + <argument> + <dataUse xsi:type="tdl:OmitValue" name="omit"/> + <parameter xsi:type="tdl:Member" href="step3body.json-generated.tdltx#//@packagedElement.4/@member.0"/> + <reduction> + <collectionIndex xsi:type="tdl:LiteralValueUse" intValue="2"/> + </reduction> + </argument> + <argument> + <dataUse xsi:type="tdl:OmitValue" name="omit"/> + <parameter xsi:type="tdl:Member" href="step3body.json-generated.tdltx#//@packagedElement.4/@member.0"/> + <reduction> + <collectionIndex xsi:type="tdl:LiteralValueUse" intValue="3"/> + </reduction> + <reduction> + <member href="step3body.json-generated.tdltx#//@packagedElement.6/@member.2"/> + <collectionIndex xsi:type="tdl:LiteralValueUse" intValue="1"/> + </reduction> + </argument> + <dataElement xsi:type="tdl:StructuredDataInstance" href="step3body.json-generated.tdltx#//@packagedElement.18"/> + </dataUse> + <parameter xsi:type="tdl:Member" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.7/@member.3"/> + </argument> + <dataElement xsi:type="tdl:StructuredDataInstance" href="HTTP.tdltx#//@nestedPackage.1/@packagedElement.15"/> + </argument> + </behaviour> + </block> + </behaviour> + </block> + </behaviour> + <guard> + <expression xsi:type="tdl:PredefinedFunctionCall"> + <function href="Standard.tdltx#//@packagedElement.28"/> + <actualParameters xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.2"/> + <actualParameters xsi:type="tdl:DataElementUse" dataElement="//@packagedElement.3"/> + </expression> + </guard> + </block> + </behaviour> + </behaviourDescription> + <testObjective href="Objectives.tdltx#//@packagedElement.6"/> + </packagedElement> + <import> + <importedPackage href="Standard.tdltx#/"/> + </import> + <import> + <importedPackage href="Objectives.tdltx#/"/> + </import> + <import> + <importedPackage href="Config.tdltx#/"/> + </import> + <import> + <importedPackage href="step3body.json-generated.tdltx#/"/> + </import> + <import> + <importedPackage href="step2body.json-generated.tdltx#/"/> + </import> + <import> + <importedPackage href="HTTP.tdltx#//@nestedPackage.1"/> + </import> +</tdl:Package> diff --git a/mwt-examples/src/tdl/HTTP.tdltx b/mwt-examples/src/tdl/HTTP.tdltx new file mode 100644 index 0000000..e77481c --- /dev/null +++ b/mwt-examples/src/tdl/HTTP.tdltx @@ -0,0 +1,126 @@ +Package HTTP { + Package MessageBasedConfiguration { + Import all from MessageBased + Message Gate HTTPGate accepts Request,Response + Component API { + //Add variables and timers here or define new component types and configurations + gate HTTPGate http + } + Configuration BasicClientServer { + API client as Tester, + API server as SUT, + connect client::http to server::http + } + + } Note : "Message based types and instances" + + Package MessageBased { + Import all from Standard + + //Generic Method type -> required for generation!!! + Enumerated Method { + Method GET, + Method POST, + Method PUT, + Method PATCH, + Method DELETE + } + + //Generic Request type + Structure Request ( + String uri, + optional Method method, + optional Headers headers, + optional Parameters parameters, + optional Body body + ) + + //Generic Request instances + Request rGET (method = GET) + Request rPOST (method = POST) + Request PUT (method = PUT) + Request PATCH (method = PATCH) + Request DELETE (method = DELETE) + + //Generic Response type + Structure Response ( + optional Integer status, + optional String statusMessage, + optional Headers headers, + optional Body body + ) + + //Generic Response instances, name = status code + + Response r200 (statusMessage = "OK") + Response r201 (statusMessage = "Created") + Response r204 (statusMessage = "No Content") + Response r400 (statusMessage = "Bad Request") + Response r401 (statusMessage = "Not Found") + Response r403 (statusMessage = "Not Authorized") + Response r404 (statusMessage = "Forbidden") + + //Generic Response instances, name = status message + Response OK (status = "200") + Response Created (status = "201") + Response NoContent (status = "204") + Response BadRequest (status = "400") + Response NotFound (status = "404") + Response NotAuthorized (status = "401") + Response Forbidden (status = "403") + + //supporting types + Collection Parameters of Parameter + Structure Parameter ( + Location location, + String ^name, + String ^value + ) + Type Location + Location path + Location query + + //may need a structure, not necessarily relevant in standardized testing + Location cookie + + //separate headers -> not necessary + //Location header; + Collection Headers of Header + Structure Header ( + String ^name, + String ^value + //not relevant in TDL? + //optional contentLength of type Integer, + //optional contentType of type String + ) + + //Base body for extension + Structure Body ( ) + + //Basic string body + Structure StringBody extends Body ( + String text + ) + + //Basic wrapper for collection responses + Structure CollectionBody extends Body ( + Bodies items + ) + + //Any body can be included + //If consistent type is needed, a custom subtype shall be defined and used + Collection Bodies of Body + + //Custom collection data instances can be defined + // - inline in the responses + // - predefined as a separate data element + //Custom collection data instances can be defined + //to enforce type consistency specific for API + + //Basic form body + Structure FormBody extends Body ( + String field, + String content + ) + } +} \ No newline at end of file diff --git a/mwt-examples/src/tdl/Objectives.tdltx b/mwt-examples/src/tdl/Objectives.tdltx new file mode 100644 index 0000000..d1c24aa --- /dev/null +++ b/mwt-examples/src/tdl/Objectives.tdltx @@ -0,0 +1,64 @@ +Package Objectives { + Import all from Standard + + Objective TD_MDD_01 { + Description: "Issue a request via Postman to all domain controllers, + to check the overall viability of the test network." + References: "ETSI Plugtests Test Plan V1.0 (2020-11), 8.3.2" + } + + Objective TD_MDD_02 { + Description: "The microwave topology information are requested from + all DCs connected to the NBI LAN at the same time for + the same information as TD_SDD_02. This allows to check + that the connectivity to all DC is fully functional. A + comparison of the answers received may be performed to + check consistency and compliance." + References: "ETSI Plugtests Test Plan V1.0 (2020-11), 8.3.2" + } + + Objective TD_MDD_03 { + Description: "The Ethernet topology information are requested + from all DCs connected to the NBI LAN at the same + time for the same information as TD_SDD_03. This + allows to check that the connectivity to all DC + is fully functional. A comparison of the answers + received may be performed to check consistency + and compliance." + References: "ETSI Plugtests Test Plan V1.0 (2020-11), 8.5.2" + } + + + Objective TD_MSP_01 { + Description: "Create the specified L2 data services over all + available domains. The TGA confirms that data + start flowing. The traffic on the inter-domain + links is classified based on S- VLAN only." + References: "ETSI Plugtests Test Plan V1.0 (2020-11), 8.5.2" + } + + Objective TD_MSP_02 { + Description: "The Ethernet service information is requested from + all the DCs under test in TD_MSP_01. The received + information is checked to correctly list the newly + created services." + References: "ETSI Plugtests Test Plan V1.0 (2020-11), 8.5.2" + } + + + Objective TD_MSP_03 { + Description: "Delete the specified L2 data service over all available + domains. The TGA confirms that data stops flowing." + References: "ETSI Plugtests Test Plan V1.0 (2020-11), 8.5.2" + } + + Objective TD_MSP_04 { + //TODO: remove formatting spaces? + Description: "The Ethernet service information is requested from all + the DCs under test in TD_MSP_03. The received + information is checked to correctly not list the newly + deleted services anymore." + References: "ETSI Plugtests Test Plan V1.0 (2020-11), 8.5.2" + } + +} \ No newline at end of file diff --git a/mwt-examples/src/tdl/Standard.tdltx b/mwt-examples/src/tdl/Standard.tdltx new file mode 100644 index 0000000..9af8d10 --- /dev/null +++ b/mwt-examples/src/tdl/Standard.tdltx @@ -0,0 +1,56 @@ +Package Standard { + //TODO: extract to standard library + Constraint length + Constraint minLength + Constraint maxLength + Constraint range + Constraint format + Constraint union + Constraint uniontype + + Type Boolean + Type Integer + Type String + Type Verdict + + //TODO: these do not work at present -> literal values take precedence? +// Boolean true +// Boolean false + Boolean True + Boolean False + + Verdict pass + Verdict fail + Verdict inconclusive + + Time second + + Annotation Master + Annotation MappingName + + //standard annotations for STO + Annotation Initial conditions + Annotation Expected behaviour + Annotation Final conditions + Annotation Test Purpose Description + Annotation when + Annotation then + + Predefined == returns Boolean + Predefined != returns Boolean + Predefined and returns Boolean + Predefined or returns Boolean + Predefined xor returns Boolean + Predefined not returns Boolean + Predefined < returns Boolean + Predefined > returns Boolean + Predefined <= returns Boolean + Predefined >= returns Boolean + Predefined + + Predefined - + Predefined * + Predefined / + Predefined mod + Predefined size returns Integer + +} \ No newline at end of file diff --git a/mwt-examples/src/tdl/step2body.json b/mwt-examples/src/tdl/step2body.json new file mode 100644 index 0000000..a36acb5 --- /dev/null +++ b/mwt-examples/src/tdl/step2body.json @@ -0,0 +1,12 @@ +{ + "etht-svc-bandwidth-profiles": [ + { + "bandwidth-profile-name": "bw_profile_{{TD_SDN_SERVICE_NAME}}", + "bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp", + "CIR": "{{TD_SDN_CIR_VALUE}}", + "EIR": "{{TD_SDN_EIR_VALUE}}", + "color-aware": true, + "coupling-flag": true + } + ] +} \ No newline at end of file diff --git a/mwt-examples/src/tdl/step2body.json-generated.tdltx b/mwt-examples/src/tdl/step2body.json-generated.tdltx new file mode 100644 index 0000000..f9c09fd --- /dev/null +++ b/mwt-examples/src/tdl/step2body.json-generated.tdltx @@ -0,0 +1,43 @@ +Package generated_from_step2body_json { + Type String + Type TODO_RESOLVE_REFERENCED + Use "step2body.json" as SOURCE_MAPPING + Type JSON_String + Structure JSON_step2body_json ( + JSON_etht_svc_bandwidth_profiles etht_svc_bandwidth_profiles + ) + Collection JSON_etht_svc_bandwidth_profiles of JSON_etht_svc_bandwidth_profiles_item + Structure JSON_etht_svc_bandwidth_profiles_item ( + JSON_String bandwidth_profile_name, + JSON_String bandwidth_profile_type, + JSON_String CIR, + JSON_String EIR, + JSON_String color_aware, + JSON_String coupling_flag + ) + + //Just use mappings? or replace with variables? (if dynamic) + JSON_step2body_json JSON_instance ( + etht_svc_bandwidth_profiles = [ + ( + bandwidth_profile_name = "bw_profile_{{TD_SDN_SERVICE_NAME}}", + bandwidth_profile_type = "ietf-eth-tran-types:mef-10-bwp", + CIR = "{{TD_SDN_CIR_VALUE}}", + EIR = "{{TD_SDN_EIR_VALUE}}", + color_aware = "true", + coupling_flag = "true" + ) + ] + ) + Map JSON_step2body_json to "JSON" in SOURCE_MAPPING as JSON_SOURCE_MAPPING { + etht_svc_bandwidth_profiles -> "etht-svc-bandwidth-profiles" + } + Map JSON_etht_svc_bandwidth_profiles_item to "JSON.etht-svc-bandwidth-profiles.item" in SOURCE_MAPPING as JSON_etht_svc_bandwidth_profiles_item_SOURCE_MAPPING { + bandwidth_profile_name -> "bandwidth-profile-name", + bandwidth_profile_type -> "bandwidth-profile-type", + CIR -> "CIR", + EIR -> "EIR", + color_aware -> "color-aware", + coupling_flag -> "coupling-flag" + } +} \ No newline at end of file diff --git a/mwt-examples/src/tdl/step3body-translate.json b/mwt-examples/src/tdl/step3body-translate.json new file mode 100644 index 0000000..b5c0ce5 --- /dev/null +++ b/mwt-examples/src/tdl/step3body-translate.json @@ -0,0 +1,85 @@ +( + services = +[ + ( + ^name = 'S1-local', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '201'), + (accessNodeId = node2, accessLtpId = p3, tagType = 'c-vlan', vlanValue = '101', bwprofile = true) + ] + ), + ( + ^name = 'S2-local-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '202'), + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '202') + ] + ), + ( + ^name = 'S3-local-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '203'), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '203') + ] + ), + ( + ^name = 'S1-inter-d-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '204'), + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '204') + ] + ), + ( + ^name = 'S2-inter-d-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '205'), + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '205') + ] + ), + ( + ^name = 'S3-inter-d-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '206'), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '206') + ] + ), + ( + ^name = 'S4-inter-d-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '207'), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '207') + ] + ), + ( + ^name = 'S1-leaf-2', + adminStatus = 'up', + ports = [ + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '208'), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '208') + ] + ), + ( + ^name = 'S2-leaf-2', + adminStatus = 'up', + ports = [ + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '209'), + (accessNodeId = node2, accessLtpId = p3, tagType = 'c-vlan', vlanValue = '103', bwprofile = true) + ] + ), + ( + ^name = 'S3-leaf-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node2, accessLtpId = p3, tagType = 'c-vlan', vlanValue = '104', bwprofile = true), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '210') + ] + ) + ] +) \ No newline at end of file diff --git a/mwt-examples/src/tdl/step3body.json b/mwt-examples/src/tdl/step3body.json new file mode 100644 index 0000000..2e9f0bf --- /dev/null +++ b/mwt-examples/src/tdl/step3body.json @@ -0,0 +1,85 @@ +{ + services: +[ + { + name: 'S1-local', + adminStatus: 'up', + ports: [ + {accessNodeId: node1, accessLtpId: p1, tagType: 's-vlan', vlanValue: '201'}, + {accessNodeId: node2, accessLtpId: p3, tagType: 'c-vlan', vlanValue: '101', bwprofile: true}, + ] + }, + { + name: 'S2-local-1', + adminStatus: 'up', + ports: [ + {accessNodeId: node1, accessLtpId: p1, tagType: 's-vlan', vlanValue: '202'}, + {accessNodeId: node2, accessLtpId: p2, tagType: 's-vlan', vlanValue: '202'}, + ] + }, + { + name: 'S3-local-1', + adminStatus: 'up', + ports: [ + {accessNodeId: node1, accessLtpId: p1, tagType: 's-vlan', vlanValue: '203'}, + {accessNodeId: node2, accessLtpId: p4, tagType: 's-vlan', vlanValue: '203'}, + ] + }, + { + name: 'S1-inter-d-1', + adminStatus: 'up', + ports: [ + {accessNodeId: node1, accessLtpId: p1, tagType: 's-vlan', vlanValue: '204'}, + {accessNodeId: node2, accessLtpId: p2, tagType: 's-vlan', vlanValue: '204'}, + ] + }, + { + name: 'S2-inter-d-1', + adminStatus: 'up', + ports: [ + {accessNodeId: node1, accessLtpId: p1, tagType: 's-vlan', vlanValue: '205'}, + {accessNodeId: node2, accessLtpId: p2, tagType: 's-vlan', vlanValue: '205'}, + ] + }, + { + name: 'S3-inter-d-1', + adminStatus: 'up', + ports: [ + {accessNodeId: node1, accessLtpId: p1, tagType: 's-vlan', vlanValue: '206'}, + {accessNodeId: node2, accessLtpId: p4, tagType: 's-vlan', vlanValue: '206'}, + ] + }, + { + name: 'S4-inter-d-1', + adminStatus: 'up', + ports: [ + {accessNodeId: node1, accessLtpId: p1, tagType: 's-vlan', vlanValue: '207'}, + {accessNodeId: node2, accessLtpId: p4, tagType: 's-vlan', vlanValue: '207'}, + ] + }, + { + name: 'S1-leaf-2', + adminStatus: 'up', + ports: [ + {accessNodeId: node2, accessLtpId: p2, tagType: 's-vlan', vlanValue: '208'}, + {accessNodeId: node2, accessLtpId: p4, tagType: 's-vlan', vlanValue: '208'}, + ] + }, + { + name: 'S2-leaf-2', + adminStatus: 'up', + ports: [ + {accessNodeId: node2, accessLtpId: p2, tagType: 's-vlan', vlanValue: '209'}, + {accessNodeId: node2, accessLtpId: p3, tagType: 'c-vlan', vlanValue: '103', bwprofile: true}, + ] + }, + { + name: 'S3-leaf-1', + adminStatus: 'up', + ports: [ + {accessNodeId: node2, accessLtpId: p3, tagType: 'c-vlan', vlanValue: '104', bwprofile: true}, + {accessNodeId: node2, accessLtpId: p4, tagType: 's-vlan', vlanValue: '210'}, + ] + } + ] +} \ No newline at end of file diff --git a/mwt-examples/src/tdl/step3body.json-generated.tdltx b/mwt-examples/src/tdl/step3body.json-generated.tdltx new file mode 100644 index 0000000..7a37fa2 --- /dev/null +++ b/mwt-examples/src/tdl/step3body.json-generated.tdltx @@ -0,0 +1,132 @@ +Package generated_from_step3body_json { + Import all from HTTP.MessageBased + Type String + Type TODO_RESOLVE_REFERENCED + Use "step3body.json" as SOURCE_MAPPING + Type JSON_String + Structure JSON extends Body ( + optional Services services + ) + Collection Services of Service + Structure Service ( + JSON_String ^name, + JSON_String adminStatus, + Ports ports + ) + JSON_String p1 + JSON_String p2 + JSON_String p3 + JSON_String p4 + JSON_String node1 + JSON_String node2 + + //Option 1: Map to concrete values that shall be substituted using data-mappings + //Import different mappings or resolve dynamically? + + Use "companysettings" as Settings + Map p1 to "companySettings.svc['access-port1'][ 'a-link-aggr-id']" in Settings as P1_Map + Map p2 to "companySettings.svc['access-port2'][ 'i-d-link-W-id']" in Settings as P1_Map + //... + //Option 2: Use substitution inline with paths + + //Option 3: Apply functions to transform / substitute some parts + //To which extent is that needed? is it dynamic or statically initialised at start? + //-> Defer to adaptation? expose only necessary parts? + + Collection Ports of Port + Structure Port ( + JSON_String accessNodeId, + JSON_String accessLtpId, + JSON_String tagType, + JSON_String vlanValue, + JSON_String bwprofile + ) + + + + //Just use mappings? or replace with variables? (if dynamic) + JSON JSON_instance ( + services = [ + ( + ^name = 'S1-local', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '201'), + (accessNodeId = node2, accessLtpId = p3, tagType = 'c-vlan', vlanValue = '101', bwprofile = true) + ] + ), + ( + ^name = 'S2-local-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '202'), + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '202') + ] + ), + ( + ^name = 'S3-local-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '203'), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '203') + ] + ), + ( + ^name = 'S1-inter-d-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '204'), + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '204') + ] + ), + ( + ^name = 'S2-inter-d-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '205'), + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '205') + ] + ), + ( + ^name = 'S3-inter-d-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '206'), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '206') + ] + ), + ( + ^name = 'S4-inter-d-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node1, accessLtpId = p1, tagType = 's-vlan', vlanValue = '207'), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '207') + ] + ), + ( + ^name = 'S1-leaf-2', + adminStatus = 'up', + ports = [ + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '208'), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '208') + ] + ), + ( + ^name = 'S2-leaf-2', + adminStatus = 'up', + ports = [ + (accessNodeId = node2, accessLtpId = p2, tagType = 's-vlan', vlanValue = '209'), + (accessNodeId = node2, accessLtpId = p3, tagType = 'c-vlan', vlanValue = '103', bwprofile = true) + ] + ), + ( + ^name = 'S3-leaf-1', + adminStatus = 'up', + ports = [ + (accessNodeId = node2, accessLtpId = p3, tagType = 'c-vlan', vlanValue = '104', bwprofile = true), + (accessNodeId = node2, accessLtpId = p4, tagType = 's-vlan', vlanValue = '210') + ] + ) + ] + ) +} \ No newline at end of file -- GitLab