diff --git a/README.md b/README.md index ee5ea376fb69d7a2b75288c4be11b94ea849bde1..258bd338e18f07cf132baf888c7c484019a8dec9 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,229 @@ See the attached LICENSE file or visit https://forge.etsi.org/etsi-software-license ## Standard links -- Mobile-Edg Compution standards, accessible [here](https://www.etsi.org/standards#page=1&search=MEC&title=1&etsiNumber=1&content=1&version=0&onApproval=1&published=1&historical=1&startDate=1988-01-15&endDate=2019-05-06&harmonized=0&keyword=&TB=&stdType=&frequency=&mandate=&collection=&sort=1) +- Mobile-Edge Computation standards, accessible [here](https://www.etsi.org/standards#page=1&search=MEC&title=1&etsiNumber=1&content=1&version=0&onApproval=1&published=1&historical=1&startDate=1988-01-15&endDate=2019-05-06&harmonized=0&keyword=&TB=&stdType=&frequency=&mandate=&collection=&sort=1) ## RFC links - RFC 7159 - The JavaScript Object Notation (JSON) Data Interchange Format, accessible [here](https://tools.ietf.org/html/rfc7159.html) NOTE All draft can be found in the 'IETF XML Registry', accessible [here](https://www.iana.org/assignments/xml-registry/xml-registry.xhtml) + + + +## Installation + +The MEC Testing Framework project builds and tests regularly on the following platforms: + + - Linux (Ubuntu) + +Note: The [OpenSSL](https://www.openssl.org) version > 1.1.x is also required. + +### How to do it? + +They are two different methods: +- Using [Vagrant](https://www.vagrantup.com/) +- Using [Docker](https://www.docker.com/) + +How to choose one of these methods is depending of your host system. + +NOTE: In all case, if you want to setup an continuous integration process (e.g. Jenkins), Docker is the best choice. + + +#### The host system is Windows +The both methods require a virtual machine. You can use either VirtualBox or WMware. +In this case, the easiest way is to use Vagrant. + + +#### The host system is Linux +Vagrant requires a virtual machine. You can use either VirtualBox or WMware. +Docker does not need a virtual machine, so it is the more efficant way. + + +### Using Vagrant + +Pre-requisites on your host machine: +- Install [Virtualbox](https://www.virtualbox.org/manual/ch01.html) +- Install [Vagrant](https://www.vagrantup.com/intro/getting-started/) +- Install Vagrant plugin vagrant-vbguest +- Credentials to access [ETSI forge](https://forge.etsi.org/gitlab/users/sign_in) + - Set the environment variable USERNAME to your ETSI EOL account user name + - Set the environment variable PASSWORD to your ETSI EOL account password + +Procedure: +- On your host machine, open a command line session (PuTTY, DOS window...) +- From the ETSI MEC Testing Framework project, clone the Vagrant folder +- In the file Vagrantfile, modify the tag config.vm.provision replacing & strings by your ETSI credentials +- In the Vagrant folder, execute the following commands: + +```sh +$ vagrant up --provider virtualbox --provision +... +``` + +NOTE The creation and the installations will take some time to achieve +- Stop vagrant virtual machine + +```sh +$ vagrant halt +... +``` + +- Update the file 'Vagrantfile' to match with your networks configuration +- Re-start the vagrant virtual machine and log to to the machine + +```sh +$ vagrant up +... +$ vagrant ssh +``` + +- Switch to the next clause (Usage) + +NOTE The user password is vagrant. + + +### Using Docker + +Pre-requisites on your host machine: +- Install Virtualbox +- Install Docker + +Procedure for a Windows host machine: +- On your host machine, open a the Docker Quickstart Terminal +- On your host machine, clone the ETSI MEC Testing Framework project. NOTE that only Docker folder and .jenkins.sh script file are required +- From the ETSI MEC Testing Framework project root directory, execute the following commands: + +```sh +$ ./.jenkins.sh +... +``` + +NOTE The creation and the installations will take some time to achieve +- Start the container + +```sh +$ ./docker/run-container.sh +... +``` + +- Switch to the next clause (Usage) + + +### From scratch + +Pre-requisites: +- Install Virtualbox + +Procedure: +- Install a new Linux Virtual machine (Mint, Debian...) +- Update your system with the latest version of kernel and security packages +- Install the following packages (According to the Linux chosen, the package naming can be different) + autoconf + bison + build-essential + cmake + curl + dos2unix + doxygen + emacs + expect + flex + g++:latest + gcc:latest + graphviz + gdb + git-core + gnutls-bin + libglib2.0-dev + libpcap-dev + libgcrypt-dev + libncurses5-dev + libssl-dev + libtool-bin + libtool + libwireshark-dev + libxml2-dev + lsof + ntp + pkg-config + qt5-default + qtmultimedia5-dev + libqt5svg5-dev + subversion + sudo + sshpass + tcpdump + texlive-font-utils + tshark + valgrind + vim + vsftpd + xutils-dev + tree + tzdata + unzip + wget + xsltproc +- In your home directory, create the following folders: + - $HOME/frameworks, + - $HOME/dev + - $HOME/lib +- In $HOME/frameworks, build the following package: + - asn1c, according the procedure specified [here](https://github.com/vlm/asn1c.git) + - Eclipse IDE for C/C++ Developers, according the procedure specified [here](https://www.eclipse.org/cdt/) + - TITAN, according the procedure specified [here](https://github.com/eclipse/titan.core) + - Import the TITAN plugin into your Eclipse IDE, according the procedure specified [here](https://github.com/eclipse/titan.core) +- Clone the ETSI MEC Testing Framework project into $HOME/dev folder + +```sh +$ git clone +``` + +- Update your default environment with the content of the script $HOME/dev/STF569_Mec/scripts/devenv.bash.ubuntu +- Switch to the next clause (Usage) + + +## Usage + +This clause describes how to compile and execute an Abstract Test Suite. + + +Pre-requisites: +- Your machine is installed following one of the installation method describes in the previous clause +- Your are logged as 'etsi' or 'vagrant' user + +Procedure using Eclipse TITAN: +- Start eclipse using a new workspace, (e.g. with the name workspace_titan) +- Download and follow the steps to install Eclipse plugins for TITAN, accessible [here]{https://www.eclipse.org/downloads/download.php?file=/titan/Eclipse_installationguide.pdf} +- Open the workspace_titan +- Create a new TITAN project (e.g. STF569_Mec) + + +Procedure in TITAN command line: +- Open several SSH session (PuTTY...) +- Change to the directory ~/dev/STF569_Mec/src/AtsMec/objs +- Build the test suite AtsMec + +```sh +$ ../bin/mec_generate_makefile.bash +... +``` + +- Edit the file ../etc/AtsMec.cfg +- Update the following fields (see ETSI TS 103 099 for details): + - PICS_HEADER_HOST, the HTTP host header value + - system.httpPort.params +- To run the test suite, execute the following command: + +```sh +$ ../bin/run-all.bash +... +``` + +- The log files are located in ../logs folder. You can edit them using any editor or using the Eclipse TITAN log plugins + + +## How to Report a Bug + +The ETSI MEC Testing Framework project is under constant development, so it is possible that you will +encounter a bug while using it. Please report bugs at cti_support at etsi dot org. diff --git a/ccsrc/Protocols/Json/json_codec.cc b/ccsrc/Protocols/Json/json_codec.cc index 7960cf295cdf531116eea7624d419bf75dfdfe60..e422fff322dc797b5bdf095d22277ba84642ab1a 100644 --- a/ccsrc/Protocols/Json/json_codec.cc +++ b/ccsrc/Protocols/Json/json_codec.cc @@ -65,7 +65,7 @@ int json_codec::decode (const OCTETSTRING& p_data, LibItsHttp__JsonMessageBodyTy access_point_list.decode(LocationAPI__TypesAndValues::AccessPointList_descr_, decoding_buffer, TTCN_EncDec::CT_JSON); msg.accessPointList() = access_point_list; } else if (it->second.find("\"SubscriptionLinkList\"") != std::string::npos) { // Be carefull to the order - // TODO To be refined, find("\"accessPointList\"") is not optimal + // TODO To be refined, find("\"accessPointList\"") is not optimal RnisAPI__TypesAndValues::SubscriptionLinkList subscription_link_list; subscription_link_list.decode(RnisAPI__TypesAndValues::SubscriptionLinkList_descr_, decoding_buffer, TTCN_EncDec::CT_JSON); msg.subscriptionLinkList() = subscription_link_list; @@ -77,6 +77,10 @@ int json_codec::decode (const OCTETSTRING& p_data, LibItsHttp__JsonMessageBodyTy UEidentityAPI__TypesAndValues::UeIdentityTagInfo ue_identity_tag_info; ue_identity_tag_info.decode(UEidentityAPI__TypesAndValues::UeIdentityTagInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON); msg.ueIdentityTagInfo() = ue_identity_tag_info; + } else if (it->second.find("\"bwInfo\"") != std::string::npos) { + BwManagementAPI__TypesAndValues::BwInfo bw_info; + bw_info.decode(BwManagementAPI__TypesAndValues::BwInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON); + msg.bwInfo() = bw_info; } else if (it->second.find("\"problemDetails\"") != std::string::npos) { UEidentityAPI__TypesAndValues::ProblemDetails problem_details; problem_details.decode(UEidentityAPI__TypesAndValues::ProblemDetails_descr_, decoding_buffer, TTCN_EncDec::CT_JSON); diff --git a/etc/AtsMec/AtsMec.cfg b/etc/AtsMec/AtsMec.cfg index e36d99ef294c8b46d4d5653f5d7d7c5e0948777a..65a93edc611744ad0808f94a9fc945b6a4c0bd5c 100644 --- a/etc/AtsMec/AtsMec.cfg +++ b/etc/AtsMec/AtsMec.cfg @@ -7,8 +7,8 @@ LibCommon_Time.PX_TAC := 30.0 LibCommon_Sync.PX_TSYNC_TIME_LIMIT := 30.0; LibCommon_Sync.PX_TSHUT_DOWN_TIME_LIMIT := 30.0; -LibItsHttp_Pics.PICS_HEADER_HOST := "172.28.4.87" -#LibItsHttp_Pics.PICS_HEADER_HOST := "192.168.1.21" +#LibItsHttp_Pics.PICS_HEADER_HOST := "172.28.4.87" +LibItsHttp_Pics.PICS_HEADER_HOST := "192.168.1.21" LibItsHttp_Pics.PICS_HEADER_CONTENT_TYPE := "application/json" @@ -31,7 +31,7 @@ LogEventTypes:= Yes [TESTPORT_PARAMETERS] # In this section you can specify parameters that are passed to Test Ports. -system.httpPort.params := "HTTP(codecs=json:json_codec)/TCP(debug=1,server=172.28.4.87,port=8081,use_ssl=0)" +system.httpPort.params := "HTTP(codecs=json:json_codec)/TCP(debug=1,server=192.168.1.21,port=8081,use_ssl=0)" [DEFINE] # In this section you can create macro definitions, diff --git a/ttcn/AtsMec/AtsMec_BwManagementAPI_TestCases.ttcn b/ttcn/AtsMec/AtsMec_BwManagementAPI_TestCases.ttcn index 7828b0e72c717d0f1a852173bbae57f07bbdf95c..aa9027b60761a8b77e8036283931ce5dd4cd5499 100644 --- a/ttcn/AtsMec/AtsMec_BwManagementAPI_TestCases.ttcn +++ b/ttcn/AtsMec/AtsMec_BwManagementAPI_TestCases.ttcn @@ -26,6 +26,8 @@ module AtsMec_BwManagementAPI_TestCases { // LibMec/BwManagementAPI import from BwManagementAPI_TypesAndValues all; import from BwManagementAPI_Templates all; + import from BwManagementAPI_Pics all; + import from BwManagementAPI_Pixits all; // LibMec import from LibMec_Functions all; @@ -34,6 +36,63 @@ module AtsMec_BwManagementAPI_TestCases { group me_app_role { + /** + * @desc Check that the IUT responds with the list of configured bandwidth allocations when queried by a MEC Application + * @see https://forge.etsi.org/gitlab/mec/MEC-tests/blob/master/Test%20Purposes/Plat/Mp1/Bandwidth/PlatBandwidthManager.tplan2 + * @see hhttps://forge.etsi.org/swagger/ui/?url=https://forge.etsi.org/gitlab/mec/gs015-bandwith-mgmt-api/raw/master/BwManagementApi.yaml + */ + testcase TC_MEC_PLAT_MP1_BWA_BV_001() runs on HttpComponent system HttpTestAdapter { + // Local variables + var HeaderLines v_headers; + var HttpMessage v_response; + + // Test control + if (not(PICS_MEC_PLAT) or not(PICS_BWMANAGEMENT_API_SUPPORTED)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_BWMANAGEMENT_API_SUPPORTED required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cf_01_http_up(); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(-, -, v_headers); + httpPort.send( + m_http_request( + m_http_request_get( + PX_ME_BWM_URI & "?app_instance_id=" & oct2char(unichar2oct(PX_APP_INSTANCE_ID, "UTF-8")), + v_headers + ) + ) + ); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_json( + mw_body_json_bw_info( + mw_bw_info + ))))) -> value v_response { + log("*** " & testcasename() & ": PASS: IUT successfully responds with a ZoneId ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cf_01_http_down(); + } // End of testcase TC_MEC_PLAT_MP1_BWA_BV_001 + } // End of group me_app_role } // End of module AtsMec_BwManagementAPI_TestCases diff --git a/ttcn/AtsMec/AtsMec_LocationAPI_TestCases.ttcn b/ttcn/AtsMec/AtsMec_LocationAPI_TestCases.ttcn index 009da1e2e2991070ec09f6e12e92429acf9d9138..59a1b9bfb0ce4742af737e7cb4d284e0256af4c6 100644 --- a/ttcn/AtsMec/AtsMec_LocationAPI_TestCases.ttcn +++ b/ttcn/AtsMec/AtsMec_LocationAPI_TestCases.ttcn @@ -39,7 +39,7 @@ module AtsMec_LocationAPI_TestCases { /** * @desc Check that the IUT responds with a list for the location of User Equipments when queried by a MEC Application * @see https://forge.etsi.org/gitlab/mec/MEC-tests/blob/master/Test%20Purposes/Plat/Mp1/UeLocation/PlatUeLocation.tplan2 - * @see https://forge.etsi.org/gitlab/mec/gs013-location-api/blob/master/LocationAPI.yaml#/definitions/UserInfo + * @see https://forge.etsi.org/gitlab/mec/gs013-location-api/blob/master/LocationAPI.yaml */ testcase TC_MEC_PLAT_MP1_LOC_BV_001() runs on HttpComponent system HttpTestAdapter { // Local variables diff --git a/ttcn/AtsMec/AtsMec_TestControl.ttcn b/ttcn/AtsMec/AtsMec_TestControl.ttcn index 81f0c9c5713159e3d3c0da1816585ec43a9861bc..c53cdbbb0061523124803846f9c7c8f7693cdafb 100644 --- a/ttcn/AtsMec/AtsMec_TestControl.ttcn +++ b/ttcn/AtsMec/AtsMec_TestControl.ttcn @@ -6,6 +6,8 @@ module AtsMec_TestControl { import from UEidentityAPI_Pics all; // LibMec/RnisAPI import from RnisAPI_Pics all; + // LibMec/BwManagementAPI + import from BwManagementAPI_Pics all; // LibMec import from LibMec_Pics all; @@ -37,11 +39,13 @@ module AtsMec_TestControl { } } - if (PICS_RNIS) { - if (PICS_RNIS_ALL_SUBSCRIPTIONS) { - execute(TC_MEC025_RNIS_SUBSCRIPTION_005()); - } + if (PICS_RNIS_ALL_SUBSCRIPTIONS) { + execute(TC_MEC025_RNIS_SUBSCRIPTION_005()); + } + + if (PICS_BWMANAGEMENT_API_SUPPORTED) { + execute(TC_MEC_PLAT_MP1_BWA_BV_001()); } - } + } // End of 'control' statement } // End of module AtsMec_TestControl diff --git a/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Pics.ttcn b/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Pics.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..6bccd864dc0b34140bf0b8f71e294300df5d7775 --- /dev/null +++ b/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Pics.ttcn @@ -0,0 +1,8 @@ +module BwManagementAPI_Pics { + + /** + * @desc Does the IUT support BwManagementAPI? + */ + modulepar boolean PICS_BWMANAGEMENT_API_SUPPORTED := true; + +} // End of module BwManagementAPI_Pics diff --git a/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Pixits.ttcn b/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Pixits.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..6c3b8d5e42bbe9aec7576945ba63e24d63d292f1 --- /dev/null +++ b/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Pixits.ttcn @@ -0,0 +1,15 @@ +module BwManagementAPI_Pixits { + + // LibCommon + import from LibCommon_BasicTypesAndValues all; + + // LibMec/LocationAPI + import from LocationAPI_TypesAndValues all; + + modulepar Address PX_APP_INSTANCE_ID := "appInst01"; + + modulepar ResourceURL PX_RESOURCE_URL := "http://example.com/exampleAPI/location/v2/users?address:acr:192.0.0.1"; + + modulepar TimeStamp PX_TIME_STAMP := { seconds := 1483231138, nanoSeconds := 0 }; + +} // End of module BwManagementAPI_Pixits diff --git a/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Templates.ttcn b/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Templates.ttcn index f45196150aa1856e59eac3aff0c3eefaecdacb5f..bf5fa3be5a31a55ebfb538603fbae81cada4332b 100644 --- a/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Templates.ttcn +++ b/ttcn/LibMec/BwManagementApi/ttcn/BwManagementAPI_Templates.ttcn @@ -8,6 +8,7 @@ module BwManagementAPI_Templates { // LibMec/BwManagementAPI import from BwManagementAPI_TypesAndValues all; + import from BwManagementAPI_Pixits all; template (value) ProblemDetails m_problem_details( in JSON.String p_type, @@ -38,7 +39,7 @@ module BwManagementAPI_Templates { } // End of template mw_problem_details template (value) BwInfo m_bw_info( - in AppInsId p_appInsId, + in AppInsId p_appInsId := PX_APP_INSTANCE_ID, in RequestType p_requestType, in FixedBWPriority p_fixedBWPriority, in FixedAllocation p_fixedAllocation, @@ -70,7 +71,7 @@ module BwManagementAPI_Templates { } // End of template mw_bw_info template (value) BwInfoDeltas m_bw_info_delta( - in AppInsId p_appInsId, + in AppInsId p_appInsId := PX_APP_INSTANCE_ID, in RequestType p_requestType, in template (value) SessionFilter p_sessionFilter, in FixedBWPriority p_fixedBWPriority, diff --git a/ttcn/LibMec/LocationAPI/ttcn/LocationAPI_Pics.ttcn b/ttcn/LibMec/LocationAPI/ttcn/LocationAPI_Pics.ttcn index 7888074680e7776f2e4b04191af3253aae89e41a..ff054f5905d5e12709509def4d7ab41186c55344 100644 --- a/ttcn/LibMec/LocationAPI/ttcn/LocationAPI_Pics.ttcn +++ b/ttcn/LibMec/LocationAPI/ttcn/LocationAPI_Pics.ttcn @@ -1,5 +1,5 @@ module LocationAPI_Pics { - + /** * @desc Does the IUT support LocationAPI? */ diff --git a/ttcn/LibMec/ttcn/LibMec_Pixits.ttcn b/ttcn/LibMec/ttcn/LibMec_Pixits.ttcn index f48fb8c2c7a9777efa278a2bf91c4a06cefc56b2..e83458289f544fcf9950963ba30550a26d97dae1 100644 --- a/ttcn/LibMec/ttcn/LibMec_Pixits.ttcn +++ b/ttcn/LibMec/ttcn/LibMec_Pixits.ttcn @@ -10,4 +10,6 @@ module LibMec_Pixits { modulepar charstring PX_RNIS_SUBSCRITIONS_URI := "/exampleAPI/rni/v2/subscriptions/"; + modulepar charstring PX_ME_BWM_URI := "/exampleAPI/bwm/v2/bw_allocations"; + } // End of module LibMec_Pixits diff --git a/ttcn/patch_lib_http/LibItsHttp_JsonMessageBodyTypes.ttcn b/ttcn/patch_lib_http/LibItsHttp_JsonMessageBodyTypes.ttcn index 26c7d6409ebc5af21ac84960392000da08785fad..37546d232c3bd8538c94238b74d56ac6425122a5 100644 --- a/ttcn/patch_lib_http/LibItsHttp_JsonMessageBodyTypes.ttcn +++ b/ttcn/patch_lib_http/LibItsHttp_JsonMessageBodyTypes.ttcn @@ -26,6 +26,7 @@ module LibItsHttp_JsonMessageBodyTypes { SubscriptionLinkList subscriptionLinkList, CellChangeSubscription cellChangeSubscription, RnisAPI_TypesAndValues.ProblemDetails problemDetails_rnis, + BwInfo bwInfo, BwManagementAPI_TypesAndValues.ProblemDetails problemDetails_bw_management, universal charstring raw } with { diff --git a/ttcn/patch_lib_http/LibItsHttp_JsonTemplates.ttcn b/ttcn/patch_lib_http/LibItsHttp_JsonTemplates.ttcn index 76b945ef56e8fc1e892d9f4c3921776ca9f9e1d0..c7de670d9eedd512520f2cbf3c785febe7bcc87f 100644 --- a/ttcn/patch_lib_http/LibItsHttp_JsonTemplates.ttcn +++ b/ttcn/patch_lib_http/LibItsHttp_JsonTemplates.ttcn @@ -19,6 +19,9 @@ module LibItsHttp_JsonTemplates { // LibMec/RnisAPI import from RnisAPI_TypesAndValues all; import from RnisAPI_Templates all; + // LibMec/BwManagementAPI + import from BwManagementAPI_TypesAndValues all; + import from BwManagementAPI_Templates all; // TODO Add here your custom RFCs import @@ -146,4 +149,20 @@ module LibItsHttp_JsonTemplates { } // End of group rnis_subscriptions + group bw_management_api { + + template (value) JsonBody m_body_json_bw_info( + in template (value) BwInfo p_bwInfo + ) := { + bwInfo := p_bwInfo + } // End of template m_body_json_bw_info + + template (present) JsonBody mw_body_json_bw_info( + template (present) BwInfo p_bwInfo := ? + ) := { + bwInfo := p_bwInfo + } // End of template mw_body_json_bw_info + + } // End of group bw_management_api + } // End of module LibItsHttp_JsonTemplates