diff --git a/TODO.md b/TODO.md index 9283c47b672a3aee80101578e4179e43188cbe17..dc1a87479ac9b3abd00ae71f2f4bba95eb77ecf9 100644 --- a/TODO.md +++ b/TODO.md @@ -3,6 +3,43 @@ ## Introduction This file provides the list of the TODOs related to the STF 569. +## MEO + +### UEAPPCTX + +ETSI GS MEC 016 V2.1.1 + +https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPCTX/SysUeAppsContext.tplan2 + + +- TC_MEC_MEO_UEAPPCTX_001_OK To be tested + +- TC_MEC_MEO_UEAPPCTX_001_BR To be tested + +- TC_MEC_MEO_UEAPPCTX_002_OK To be tested + +- TC_MEC_MEO_UEAPPCTX_002_BR To be tested + +- TC_MEC_MEO_UEAPPCTX_002_NF To be tested + +- TC_MEC_MEO_UEAPPCTX_003_OK To be tested + +- TC_MEC_MEO_UEAPPCTX_003_NF To be tested + +- TC_MEC_MEO_UEAPPS_001_OK To be tested + +- TC_MEC_MEO_UEAPPS_001_BR To be tested + +- TC_MEC_MEO_UEAPPS_001_NF To be tested + + +### UEAPPS + +ETSI GS MEC 016 V2.1.1 + +https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPS/SysUeApplications.tplan2 + + ## SRV ### AMS diff --git a/ccsrc/Protocols/Json/json_codec.cc b/ccsrc/Protocols/Json/json_codec.cc index 2df168b7791f96a41bcd8ff82444d9b2e63d9bba..74af4c69e0d9c214daaf7d52c638cae78eeb01db 100644 --- a/ccsrc/Protocols/Json/json_codec.cc +++ b/ccsrc/Protocols/Json/json_codec.cc @@ -28,6 +28,10 @@ int json_codec::encode (const LibItsHttp__JsonMessageBodyTypes::JsonBody& msg, O const RnisAPI__TypesAndValues::CellChangeSubscription& cell_change_subscription = msg.cellChangeSubscription(); cell_change_subscription.encode(RnisAPI__TypesAndValues::CellChangeSubscription_descr_, encoding_buffer, TTCN_EncDec::CT_JSON); data = char2oct(CHARSTRING("{\"CellChangeSubscription\": ")) + OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data()) + char2oct(CHARSTRING("}")); + } else if (msg.ischosen(LibItsHttp__JsonMessageBodyTypes::JsonBody::ALT_appContext)) { + const UEAppInterfaceAPI__TypesAndValues::AppContext& appContext = msg.appContext(); + appContext.encode(UEAppInterfaceAPI__TypesAndValues::AppContext_descr_, encoding_buffer, TTCN_EncDec::CT_JSON); + data = char2oct(CHARSTRING("{\"AppContext\": ")) + OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data()) + char2oct(CHARSTRING("}")); } else { loggers::get_instance().error("json_codec::encode: Not supported"); } @@ -235,6 +239,14 @@ int json_codec::decode (const OCTETSTRING& p_data, LibItsHttp__JsonMessageBodyTy RnisAPI__TypesAndValues::RabRelSubscription rab_rel_subscription; rab_rel_subscription.decode(RnisAPI__TypesAndValues::RabRelSubscription_descr_, decoding_buffer, TTCN_EncDec::CT_JSON); msg.rabRelSubscription() = rab_rel_subscription; + } else if (it->second.find("\"AppContext\"") != std::string::npos) { + UEAppInterfaceAPI__TypesAndValues::AppContext appContext; + appContext.decode(UEAppInterfaceAPI__TypesAndValues::AppContext_descr_, decoding_buffer, TTCN_EncDec::CT_JSON); + msg.appContext() = appContext; + } else if (it->second.find("\"AppInfo\"") != std::string::npos) { + UEAppInterfaceAPI__TypesAndValues::AppInfo appInfo; + appInfo.decode(UEAppInterfaceAPI__TypesAndValues::AppInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON); + msg.appInfo() = appInfo; } else if (it->second.find("\"bwInfo\"") != std::string::npos) { BwManagementAPI__TypesAndValues::BwInfo bw_info; diff --git a/ttcn/AtsMec/AtsMec_AppEnablementAPI_TestCases.ttcn b/ttcn/AtsMec/AtsMec_AppEnablementAPI_TestCases.ttcn index 0cd833d2b605d7b5e9f83a1292e085da89cb2762..f1fda1381146f3ed8c1668876c1115d0d4dadf2f 100644 --- a/ttcn/AtsMec/AtsMec_AppEnablementAPI_TestCases.ttcn +++ b/ttcn/AtsMec/AtsMec_AppEnablementAPI_TestCases.ttcn @@ -23,7 +23,7 @@ module AtsMec_AppEnablementAPI_TestCases { import from LibItsHttp_JsonTemplates all; import from LibItsHttp_TestSystem all; - // LibMec_AppEnablementAPI + // LibMec/AppEnablementAPI import from AppEnablementAPI_Templates all; import from AppEnablementAPI_Pics all; import from AppEnablementAPI_Pixits all; diff --git a/ttcn/AtsMec/AtsMec_LocationAPI_TestCases.ttcn b/ttcn/AtsMec/AtsMec_LocationAPI_TestCases.ttcn index 060f0bbad426174f2a1cde9174b486879d3fbbb0..3bab43261377562d09e2c7d46f07244c879bc538 100644 --- a/ttcn/AtsMec/AtsMec_LocationAPI_TestCases.ttcn +++ b/ttcn/AtsMec/AtsMec_LocationAPI_TestCases.ttcn @@ -21,7 +21,7 @@ module AtsMec_LocationAPI_TestCases { import from LibItsHttp_JsonTemplates all; import from LibItsHttp_TestSystem all; - // LibMec_LocationAPI + // LibMec/LocationAPI import from LocationAPI_Templates all; import from LocationAPI_Pics all; import from LocationAPI_Pixits all; diff --git a/ttcn/AtsMec/AtsMec_RadioNodeLocationAPI_TestCases.ttcn b/ttcn/AtsMec/AtsMec_RadioNodeLocationAPI_TestCases.ttcn index c6ee32ae3dd35345e845eda7406345bb5ef217bb..8cf7a3e58a198aa995fe26aa3ad812fa41e52b76 100644 --- a/ttcn/AtsMec/AtsMec_RadioNodeLocationAPI_TestCases.ttcn +++ b/ttcn/AtsMec/AtsMec_RadioNodeLocationAPI_TestCases.ttcn @@ -23,7 +23,7 @@ module AtsMec_RadioNodeLocationAPI_TestCases { import from LibItsHttp_JsonTemplates all; import from LibItsHttp_TestSystem all; - // LibMec_LocationAPI + // LibMec/LocationAPI import from LocationAPI_TypesAndValues all; import from LocationAPI_Templates all; import from LocationAPI_Pics all; diff --git a/ttcn/AtsMec/AtsMec_RnisAPI_TestCases.ttcn b/ttcn/AtsMec/AtsMec_RnisAPI_TestCases.ttcn index 596ffce74ef5bac13257076588376e8a219c68ef..ca60a24a5ea7bf8cbfbacd567b24c19740ad8d21 100644 --- a/ttcn/AtsMec/AtsMec_RnisAPI_TestCases.ttcn +++ b/ttcn/AtsMec/AtsMec_RnisAPI_TestCases.ttcn @@ -24,7 +24,7 @@ module AtsMec_RnisAPI_TestCases { import from LibItsHttp_JsonTemplates all; import from LibItsHttp_TestSystem all; - // LibMec_RnisAPI + // LibMec/RnisAPI import from RnisAPI_TypesAndValues all; import from RnisAPI_Templates all; import from RnisAPI_Pics all; diff --git a/ttcn/AtsMec/AtsMec_TestControl.ttcn b/ttcn/AtsMec/AtsMec_TestControl.ttcn index 452f7e3ecb9699c6cb2f0db52fdfb4cb0cff4c76..ea476b4db441aa3415ffb76253cbbce36a9afc34 100644 --- a/ttcn/AtsMec/AtsMec_TestControl.ttcn +++ b/ttcn/AtsMec/AtsMec_TestControl.ttcn @@ -10,6 +10,8 @@ module AtsMec_TestControl { import from BwManagementAPI_Pics all; // LibMec/AppEnablementAPI import from AppEnablementAPI_Pics all; + // LibMec/UEAppInterfaceAPI + import from UEAppInterfaceAPI_Pics all; // LibMec import from LibMec_Pics all; @@ -21,6 +23,7 @@ module AtsMec_TestControl { import from AtsMec_RnisAPI_TestCases all; import from AtsMec_BwManagementAPI_TestCases all; import from AtsMec_AppEnablementAPI_TestCases all; + import from AtsMec_UEAppInterfaceAPI_TestCases all; control { @@ -68,6 +71,19 @@ module AtsMec_TestControl { execute(TC_MEC_SRV_TRAF_003_OK()); execute(TC_MEC_SRV_TRAF_001_NF()); } + + if (PICS_ENABLE_UE_APP_CTX) { + execute(TC_MEC_MEO_UEAPPCTX_001_OK()); + execute(TC_MEC_MEO_UEAPPCTX_001_BR()); + execute(TC_MEC_MEO_UEAPPCTX_002_OK()); + execute(TC_MEC_MEO_UEAPPCTX_002_BR()); + execute(TC_MEC_MEO_UEAPPCTX_002_NF()); + execute(TC_MEC_MEO_UEAPPCTX_003_OK()); + execute(TC_MEC_MEO_UEAPPCTX_003_NF()); + execute(TC_MEC_MEO_UEAPPS_001_OK()); + execute(TC_MEC_MEO_UEAPPS_001_BR()); + execute(TC_MEC_MEO_UEAPPS_001_NF()); + } } if (PICS_RNIS) { diff --git a/ttcn/AtsMec/AtsMec_UEAppInterfaceAPI_TestCases.ttcn b/ttcn/AtsMec/AtsMec_UEAppInterfaceAPI_TestCases.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..bf935681dc6a8f002d8d30fc3132d1a5aa7f24c6 --- /dev/null +++ b/ttcn/AtsMec/AtsMec_UEAppInterfaceAPI_TestCases.ttcn @@ -0,0 +1,641 @@ +/** + * @author ETSI / STF569 + * @version $URL:$ + * $ID:$ + * @desc This module provides the MEC test cases. + * @copyright ETSI Copyright Notification + * No part may be reproduced except as authorized by written permission. + * The copyright and the foregoing restriction extend to reproduction in all media. + * All rights reserved. + * @see ETSI GS MEC 003, Draft ETSI GS MEC 013 V2.0.3 (2018-10) + */ +module AtsMec_UEAppInterfaceAPI_TestCases { + + // Libcommon + import from LibCommon_Sync all; + + // LibHttp + import from LibItsHttp_TypesAndValues all; + import from LibItsHttp_Functions all; + import from LibItsHttp_Templates all; + import from LibItsHttp_JsonTemplates all; + import from LibItsHttp_TestSystem all; + + // LibMec/UEAppInterfaceAPI + import from UEAppInterfaceAPI_Templates all; + import from UEAppInterfaceAPI_Functions all; + import from UEAppInterfaceAPI_Pics all; + import from UEAppInterfaceAPI_Pixits all; + + // LibMec + import from LibMec_Functions all; + import from LibMec_Pics all; + import from LibMec_Pixits all; + + group ue_app_ctx { + + /** + * @desc Check that the IUT acknowledges the creation of the application context when requested by an UE Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPCTX/SysUeAppsContext.tplan2 + */ + testcase TC_MEC_MEO_UEAPPCTX_001_OK() 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_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX 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_post( + "/" & PICS_ROOT_API & PX_UE_APP_CTX_URI, + v_headers, + m_http_message_body_json( + m_body_json_app_context( + m_app_context( + PX_CONTEXT_ID, + PX_ASSOCIATE_UE_APP_ID, + m_required_app_info( + PX_APP_NAME, + PX_APP_PROVIDER, + PX_REFERENCE_URL + ))))))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_201_created( + mw_http_message_body_json( + mw_body_json_app_context( + mw_app_context( + -, + -, + mw_required_app_info( + PX_APP_NAME + ))))))) -> value v_response { + tc_ac.stop; + + if (f_check_headers(v_response.response.header) == true) { + log("*** " & testcasename() & ": PASS: IUT successfully responds with a AppContext ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Header 'Location' was not present in the response headers ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] 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_MEO_UEAPPCTX_001_OK + + /** + * @desc Check that the IUT responds with an error when a request with incorrect parameters is sent by a MEC Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPCTX/SysUeAppsContext.tplan2 + */ + testcase TC_MEC_MEO_UEAPPCTX_001_BR() runs on HttpComponent system HttpTestAdapter { + // Local variables + var HeaderLines v_headers; + + // Test control + if (not(PICS_MEC_PLAT) or not(PICS_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX 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_post( + "/" & PICS_ROOT_API & PX_UE_APP_CTX_URI, + v_headers, + m_http_message_body_json( + m_body_json_app_context( + m_app_context( + PX_CONTEXT_ID, + PX_ASSOCIATE_UE_APP_ID, + m_required_app_info( + PX_APP_NAME, + PX_APP_PROVIDER, + PX_REFERENCE_URL + ))))))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_400_bad_request + )) { + tc_ac.stop; + + log("*** " & testcasename() & ": PASS: IUT successfully responds with a AppTerminationNotificationSubscription ***"); + 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_MEO_UEAPPCTX_001_BR + + /** + * @desc Check that the IUT updates the application callback reference when commanded by an UE Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPCTX/SysUeAppsContext.tplan2 + */ + testcase TC_MEC_MEO_UEAPPCTX_002_OK() runs on HttpComponent system HttpTestAdapter { + // Local variables + var HeaderLines v_headers; + + // Test control + if (not(PICS_MEC_PLAT) or not(PICS_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cf_01_http_up(); + + // Test adapter configuration + + // Preamble + f_create_ue_app_ctx(); + f_init_default_headers_list(-, -, v_headers); + httpPort.send( + m_http_request( + m_http_request_post( + "/" & PICS_ROOT_API & PX_UE_APP_CTX_URI & "/" & oct2char(unichar2oct(PX_CONTEXT_ID)), + v_headers, + m_http_message_body_json( + m_body_json_app_context( + m_app_context( + PX_CONTEXT_ID, + PX_ASSOCIATE_UE_APP_ID, + m_required_app_info( + PX_APP_NAME, + PX_APP_PROVIDER, + PX_REFERENCE_URL + ), + PX_CALLBACK_REF + )))))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_204_no_content + )) { + tc_ac.stop; + + log("*** " & testcasename() & ": PASS: IUT successfully responds with a AppContext ***"); + 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_delete_ue_app_ctx(); + f_cf_01_http_down(); + } // End of testcase TC_MEC_MEO_UEAPPCTX_002_OK + + /** + * @desc Check that the IUT responds with an error when a request with incorrect parameters is sent by a MEC Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPCTX/SysUeAppsContext.tplan2 + */ + testcase TC_MEC_MEO_UEAPPCTX_002_BR() runs on HttpComponent system HttpTestAdapter { + // Local variables + var HeaderLines v_headers; + + // Test control + if (not(PICS_MEC_PLAT) or not(PICS_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX 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_post( + "/" & PICS_ROOT_API & PX_UE_APP_CTX_URI & "/" & oct2char(unichar2oct(PX_CONTEXT_ID)), + v_headers, + m_http_message_body_json( + m_body_json_app_context( + m_app_context( + PX_CONTEXT_ID, + PX_ASSOCIATE_UE_APP_ID, + m_required_app_info( + PX_APP_NAME, + PX_APP_PROVIDER, + PX_REFERENCE_URL + ), + PX_CALLBACK_REF + )))))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_400_bad_request + )) { + tc_ac.stop; + + log("*** " & testcasename() & ": PASS: IUT successfully responds with a AppContext ***"); + 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_MEO_UEAPPCTX_002_BR + + /** + * @desc Check that the IUT responds with an error when a request for an unknown URI is sent by a MEC Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPCTX/SysUeAppsContext.tplan2 + */ + testcase TC_MEC_MEO_UEAPPCTX_002_NF() runs on HttpComponent system HttpTestAdapter { + // Local variables + var HeaderLines v_headers; + + // Test control + if (not(PICS_MEC_PLAT) or not(PICS_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX 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_post( + "/" & PICS_ROOT_API & PX_UE_APP_CTX_URI & "/" & oct2char(unichar2oct(PX_CONTEXT_ID)), + v_headers, + m_http_message_body_json( + m_body_json_app_context( + m_app_context( + PX_NON_EXISTENT_CONTEXT_ID, + PX_ASSOCIATE_UE_APP_ID, + m_required_app_info( + PX_APP_NAME, + PX_APP_PROVIDER, + PX_REFERENCE_URL + ), + PX_CALLBACK_REF + )))))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_404_not_found + )) { + tc_ac.stop; + + log("*** " & testcasename() & ": PASS: IUT successfully responds with a AppContext ***"); + 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_MEO_UEAPPCTX_002_NF + + /** + * @desc Check that the IUT deletes the application context when commanded by an UE Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPCTX/SysUeAppsContext.tplan2 + */ + testcase TC_MEC_MEO_UEAPPCTX_003_OK() runs on HttpComponent system HttpTestAdapter { + // Local variables + var HeaderLines v_headers; + + // Test control + if (not(PICS_MEC_PLAT) or not(PICS_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cf_01_http_up(); + + // Test adapter configuration + + // Preamble + f_create_ue_app_ctx(); + f_init_default_headers_list(-, -, v_headers); + httpPort.send( + m_http_request( + m_http_request_delete( + "/" & PICS_ROOT_API & PX_UE_APP_CTX_URI & "/" & oct2char(unichar2oct(PX_CONTEXT_ID)), + v_headers + ))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_204_no_content + )) { + tc_ac.stop; + + log("*** " & testcasename() & ": PASS: IUT successfully delete AppContext ***"); + 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_MEO_UEAPPCTX_003_OK + + /** + * @desc Check that the IUT responds with an error when a request for an unknown URI is sent by a MEC Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPCTX/SysUeAppsContext.tplan2 + */ + testcase TC_MEC_MEO_UEAPPCTX_003_NF() runs on HttpComponent system HttpTestAdapter { + // Local variables + var HeaderLines v_headers; + + // Test control + if (not(PICS_MEC_PLAT) or not(PICS_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cf_01_http_up(); + + // Test adapter configuration + + // Preamble + f_create_ue_app_ctx(); + f_init_default_headers_list(-, -, v_headers); + httpPort.send( + m_http_request( + m_http_request_delete( + "/" & PICS_ROOT_API & PX_UE_APP_CTX_URI & "/" & oct2char(unichar2oct(PX_NON_EXISTENT_CONTEXT_ID)), + v_headers + ))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_404_not_found + )) { + tc_ac.stop; + + log("*** " & testcasename() & ": PASS: IUT successfully delete AppContext ***"); + 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_MEO_UEAPPCTX_003_NF + + } // End of group ue_app_ctx + + group ue_apps { + + /** + * @desc Check that the IUT responds with the list of user applications available when requested by an UE Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPS/SysUeApplications.tplan2 + */ + testcase TC_MEC_MEO_UEAPPS_001_OK() 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_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cf_01_http_up(); + + // Test adapter configuration + + // Preamble + f_create_ue_app_ctx(); + f_init_default_headers_list(-, -, v_headers); + httpPort.send( + m_http_request( + m_http_request_get( + "/" & PICS_ROOT_API & PX_UE_APPS_URI & "&appName=" & oct2char(unichar2oct(PX_APP_NAME)), + 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_app_info( + { *, mw_appInfo_list(PX_APP_NAME), *} + ))))) { + tc_ac.stop; + + log("*** " & testcasename() & ": PASS: IUT successfully responds with a AppInfo ***"); + 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_create_ue_app_ctx(); + f_cf_01_http_down(); + } // End of testcase TC_MEC_MEO_UEAPPS_001_OK + + /** + * @desc Check that the IUT responds with an error when a request with incorrect parameters is sent by a MEC Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPS/SysUeApplications.tplan2 + */ + testcase TC_MEC_MEO_UEAPPS_001_BR() 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_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cf_01_http_up(); + + // Test adapter configuration + + // Preamble + f_create_ue_app_ctx(); + f_init_default_headers_list(-, -, v_headers); + httpPort.send( + m_http_request( + m_http_request_get( + "/" & PICS_ROOT_API & PX_UE_APPS_URI & "&appName=" & oct2char(unichar2oct(PX_APP_NAME)) & "&serviceCont=unknown", // Wrong URI + v_headers + ))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_400_bad_request + )) { + tc_ac.stop; + + log("*** " & testcasename() & ": PASS: IUT successfully responds with a AppInfo ***"); + 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_create_ue_app_ctx(); + f_cf_01_http_down(); + } // End of testcase TC_MEC_MEO_UEAPPS_001_BR + + /** + * @desc Check that the IUT responds with an error when a request for an unknown URI is sent by a MEC Application + * @see https://forge.etsi.org/rep/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/MEO/UEAPPS/SysUeApplications.tplan2 + */ + testcase TC_MEC_MEO_UEAPPS_001_NF() 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_SERVICES) or not(PICS_ENABLE_UE_APP_CTX)) { + log("*** " & testcasename() & ": PICS_MEC_PLAT and PICS_SERVICES and PICS_ENABLE_UE_APP_CTX 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( + "/" & PICS_ROOT_API & PX_UE_APPS_URI & "&appName=" & oct2char(unichar2oct(PX_NON_EXISTENT_APP_NAME)), + v_headers + ))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_404_not_found + )) { + tc_ac.stop; + + log("*** " & testcasename() & ": PASS: IUT successfully responds with a AppInfo ***"); + 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_MEO_UEAPPS_001_NF + + } // End of group ue_apps + +} // End of module AtsMec_UEAppInterfaceAPI_TestCases diff --git a/ttcn/AtsMec/AtsMec_UEidentityAPI_TestCases.ttcn b/ttcn/AtsMec/AtsMec_UEidentityAPI_TestCases.ttcn index 6e0ea09e309f8632d57e4c6dd4688be81f2f61ac..2ac7bb51d62e7c0e89e87b81712d7dc94bb3dbca 100644 --- a/ttcn/AtsMec/AtsMec_UEidentityAPI_TestCases.ttcn +++ b/ttcn/AtsMec/AtsMec_UEidentityAPI_TestCases.ttcn @@ -21,7 +21,7 @@ module AtsMec_UEidentityAPI_TestCases { import from LibItsHttp_JsonTemplates all; import from LibItsHttp_TestSystem all; - // LibMec_UEidentityAPI + // LibMec/UEidentityAPI import from UEidentityAPI_Templates all; import from UEidentityAPI_Pics all; import from UEidentityAPI_Pixits all; diff --git a/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Functions.ttcn b/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Functions.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..ae507728316150bd10bf6efc3da389f418a45d73 --- /dev/null +++ b/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Functions.ttcn @@ -0,0 +1,109 @@ +module UEAppInterfaceAPI_Functions { + + // LibHttp + import from LibItsHttp_TypesAndValues all; + import from LibItsHttp_Functions all; + import from LibItsHttp_Templates all; + import from LibItsHttp_JsonTemplates all; + import from LibItsHttp_TestSystem all; + + // LibMec/UEAppInterfaceAPI + import from UEAppInterfaceAPI_Templates all; + import from UEAppInterfaceAPI_Pixits all; + + // LibMec + import from LibMec_Pics all; + import from LibMec_Pixits all; + + group create_ue { + + function f_create_ue_app_ctx() runs on HttpComponent system HttpTestAdapter return integer { + // Local variables + var HeaderLines v_headers; + var HttpMessage v_response; + var integer v_result := -1; + + // Send createion request + f_init_default_headers_list(-, -, v_headers); + httpPort.send( + m_http_request( + m_http_request_post( + "/" & PICS_ROOT_API & PX_UE_APP_CTX_URI, + v_headers, + m_http_message_body_json( + m_body_json_app_context( + m_app_context( + PX_CONTEXT_ID, + PX_ASSOCIATE_UE_APP_ID, + m_required_app_info( + PX_APP_NAME, + PX_APP_PROVIDER, + PX_REFERENCE_URL + ))))))); + // Wait for the response + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_201_created( + mw_http_message_body_json( + mw_body_json_app_context( + mw_app_context( + -, + -, + mw_required_app_info( + PX_APP_NAME + ))))))) -> value v_response { + tc_ac.stop; + + v_result := 0; + log("*** " & testcasename() & ": INFO: IUT successfully responds with a AppContext ***"); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + } + } // End of 'alt' statement + + return v_result; + } // End of function f_create_ue_app_ctx + + } // End of group create_ue + + group delete_ue { + + function f_delete_ue_app_ctx() runs on HttpComponent system HttpTestAdapter return integer { + // Local variables + var HeaderLines v_headers; + var integer v_result := -1; + + // Send createion request + f_init_default_headers_list(-, -, v_headers); + httpPort.send( + m_http_request( + m_http_request_delete( + "/" & PICS_ROOT_API & PX_UE_APP_CTX_URI, + v_headers + ))); + // Wait for the response + tc_ac.start; + alt { + [] httpPort.receive( + mw_http_response( + mw_http_response_204_no_content + )) { + tc_ac.stop; + + v_result := 0; + log("*** " & testcasename() & ": INFO: IUT successfully responds with a AppContext ***"); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + } + } // End of 'alt' statement + + return v_result; + } // End of function f_delete_ue_app_ctx + + } // End of group delete_ue + +} // End of module UEAppInterfaceAPI_Functions diff --git a/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Pics.ttcn b/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Pics.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..374d4ed5d1ca8c3fca06802d50d99c2fbe2c401f --- /dev/null +++ b/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Pics.ttcn @@ -0,0 +1,5 @@ +module UEAppInterfaceAPI_Pics { + + modulepar boolean PICS_ENABLE_UE_APP_CTX := false; + +} // End of UEAppInterfaceAPI_Pics diff --git a/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Pixits.ttcn b/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Pixits.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..79ae2b679e31de1d00e282726dd19aa4650e3fa5 --- /dev/null +++ b/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Pixits.ttcn @@ -0,0 +1,22 @@ +module UEAppInterfaceAPI_Pixits { + + // LibMec/EUAppInterfaceAPI + import from UEAppInterfaceAPI_TypesAndValues all; + + modulepar AppName PX_APP_NAME := "MyWornderfulApp"; + + modulepar AppName PX_NON_EXISTENT_APP_NAME := "unknownName"; + + modulepar ContextId PX_CONTEXT_ID := "ueIdAppCtx01"; + + modulepar ContextId PX_NON_EXISTENT_CONTEXT_ID := "ueIdAppCtx99"; + + modulepar AssociateUeAppId PX_ASSOCIATE_UE_APP_ID := "associateUeAppId"; + + modulepar AppProvider PX_APP_PROVIDER := "ACME & Co"; + + modulepar ReferenceURL PX_REFERENCE_URL := "referenceUrl"; + + modulepar CallbackReference PX_CALLBACK_REF := "http://www.acme.com/MyWonderfulApp/v1"; + +} // End of UEAppInterfaceAPI_Pixits diff --git a/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Templates.ttcn b/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Templates.ttcn index af1b7f97bd65c6a48571ec0e80b83b8aae98b551..f94dab4a8d1d25428ea65bbe7f4803ddd6029b51 100644 --- a/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Templates.ttcn +++ b/ttcn/LibMec/UEAppInterfaceAPI/ttcn/UEAppInterfaceAPI_Templates.ttcn @@ -43,15 +43,16 @@ module UEAppInterfaceAPI_Templates { vendorSpecificExt := p_vendor_specific_ext } // End of template mw_application_list - template (value) AppContext m_app_context( - in template (value) ContextId p_context_id, - in template (value) AssociateUeAppId p_associate_ue_app_id, - in template (value) RequiredAppInfo p_app_info - ) := { + template (omit) AppContext m_app_context( + in template (value) ContextId p_context_id, + in template (value) AssociateUeAppId p_associate_ue_app_id, + in template (value) RequiredAppInfo p_app_info, + in template (omit) CallbackReference p_callbackReference := omit + ) := { contextId := p_context_id, associateUeAppId := p_associate_ue_app_id, appInfo := p_app_info, - callbackReference := omit + callbackReference := p_callbackReference } // End of template m_app_context template (present) AppContext mw_app_context( diff --git a/ttcn/LibMec/ttcn/LibMec_Functions.ttcn b/ttcn/LibMec/ttcn/LibMec_Functions.ttcn index 98d017d9ce81508a6195f54e37ff95ab4a333352..17f05f38501d82aecf4b38935eb51bf092821423 100644 --- a/ttcn/LibMec/ttcn/LibMec_Functions.ttcn +++ b/ttcn/LibMec/ttcn/LibMec_Functions.ttcn @@ -122,13 +122,14 @@ module LibMec_Functions { */ function f_check_headers( in HeaderLines p_headers, + in charstring p_header_name := "Location", in template (present) charstring p_value := ? ) return boolean { // Local variables var boolean v_header_matched := false; for (var integer v_idx := 0; v_idx < lengthof(p_headers); v_idx := v_idx + 1) { - if (p_headers[v_idx].header_name == "Location") { + if (p_headers[v_idx].header_name == p_header_name) { if (match(p_headers[v_idx].header_value[0], p_value) == true) { v_header_matched := true; } // else, nothing to do diff --git a/ttcn/LibMec/ttcn/LibMec_Pixits.ttcn b/ttcn/LibMec/ttcn/LibMec_Pixits.ttcn index 1085e7873a7e540a7ddf95b95d77b237cf1acaf3..288bf41409e34577744bd29de342c0578ef03a5c 100644 --- a/ttcn/LibMec/ttcn/LibMec_Pixits.ttcn +++ b/ttcn/LibMec/ttcn/LibMec_Pixits.ttcn @@ -23,7 +23,7 @@ module LibMec_Pixits { modulepar charstring PX_RNIS_QUERIES_URI := "/rni/v2/queries"; modulepar charstring PX_ME_BWM_URI := "/bwm/v2/bw_allocations"; - + modulepar charstring PX_ME_APP_AMS_URI := "/amsi/v1/appMobilityServices" modulepar charstring PX_ME_APP_AMS_SUBS := "/amsi/v1/subscriptions" @@ -31,7 +31,7 @@ module LibMec_Pixits { modulepar charstring PX_MEO_GRANT_URI := "/granting/v1/grants" modulepar charstring PX_MEO_PKGM_URI := "/apmi/v1/app_packages" - + modulepar charstring PX_MEO_PKGM_SUBS := "/apmi/v1/subscriptions" modulepar charstring PX_MEPM_PKGM_URI := "/apmi/v1/app_packages" @@ -42,4 +42,9 @@ module LibMec_Pixits { modulepar charstring PX_MEX_LCM_SUBS := "/alcmi/v1/subscriptions" + + modulepar charstring PX_UE_APP_CTX_URI := "/mx2/v2/app_contexts"; + + modulepar charstring PX_UE_APPS_URI := "/mx2/v2/app_list"; + } // End of module LibMec_Pixits diff --git a/ttcn/patch_lib_http/LibItsHttp_JsonMessageBodyTypes.ttcn b/ttcn/patch_lib_http/LibItsHttp_JsonMessageBodyTypes.ttcn index f56e8ec797f4f37436aa0d294fec4cd352923fa9..645983f4c029847bfc781c76e5dc8ba24a7a0d2e 100644 --- a/ttcn/patch_lib_http/LibItsHttp_JsonMessageBodyTypes.ttcn +++ b/ttcn/patch_lib_http/LibItsHttp_JsonMessageBodyTypes.ttcn @@ -21,6 +21,10 @@ module LibItsHttp_JsonMessageBodyTypes { import from AppLCM_TypesAndValues all; + // LibMec/UEAppInterfaceAPI + import from UEAppInterfaceAPI_TypesAndValues all; + + /** * This file volontary contains a trivial declaration of the type JsonBody. * In accordance with your TTCN-3 module LibItsHttp_JSONTypes, you have to change the JsonBody typing. @@ -90,6 +94,9 @@ module LibItsHttp_JsonMessageBodyTypes { AppLCM_TypesAndValues.CreateAppInstanceRequestWithError createAppInstanceRequestWithError, AppLCM_TypesAndValues.AppInstanceInfoList appInstanceInfoList, AppLCM_TypesAndValues.InstantiateAppRequest appInstanceInstantiate, + AppContext appContext, + AppInfo appInfo, + UEAppInterfaceAPI_TypesAndValues.ProblemDetails problemDetails_ue_app_ctxt, universal charstring raw } with { variant "" diff --git a/ttcn/patch_lib_http/LibItsHttp_JsonTemplates.ttcn b/ttcn/patch_lib_http/LibItsHttp_JsonTemplates.ttcn index 7087ea09163d1114b4067b73fd36a4e15d0acc5c..4d21400fbddf5bd51287dc0dbdbdf97b6485c59e 100644 --- a/ttcn/patch_lib_http/LibItsHttp_JsonTemplates.ttcn +++ b/ttcn/patch_lib_http/LibItsHttp_JsonTemplates.ttcn @@ -43,6 +43,10 @@ module LibItsHttp_JsonTemplates { import from AppLCM_TypesAndValues all; import from AppLCM_Templates all; + + // LibMec/AppEnablementAPI + import from UEAppInterfaceAPI_TypesAndValues all; + import from UEAppInterfaceAPI_Templates all; // TODO Add here your custom RFCs import @@ -700,4 +704,44 @@ group ams_api { } // End of group svc_mgmt + group ue_app_ctx { + + template (value) JsonBody m_body_json_app_context( + in template (value) AppContext p_appContext + ) := { + appContext := p_appContext + } // End of template m_body_json_app_context + + template (present) JsonBody mw_body_json_app_context( + template (present) AppContext p_appContext := ? + ) := { + appContext := p_appContext + } // End of template mw_body_json_app_context + + template (value) JsonBody m_body_json_app_info( + in template (value) AppInfo p_appInfo + ) := { + appInfo := p_appInfo + } // End of template m_body_json_app_info + + template (present) JsonBody mw_body_json_app_info( + template (present) AppInfo p_appInfo := ? + ) := { + appInfo := p_appInfo + } // End of template mw_body_json_app_info + + template (value) JsonBody m_body_json_ue_app_ctx_problem_details( + in template (value) UEAppInterfaceAPI_TypesAndValues.ProblemDetails p_problemDetails + ) := { + problemDetails_ue_app_ctxt := p_problemDetails + } // End of template m_body_json_ue_app_ctx_problem_details + + template (present) JsonBody mw_body_json_ue_app_ctx_problem_details( + template (present) UEAppInterfaceAPI_TypesAndValues.ProblemDetails p_problemDetails := ? + ) := { + problemDetails_ue_app_ctxt := p_problemDetails + } // End of template mw_body_json_ue_app_ctx_problem_details + + } // End of group ue_app_ctx + } // End of module LibItsHttp_JsonTemplates